2018.7.13
day09回顾:
传参
把数据传递给函数
传递方式:
- 位置传参
- 序列传参
- 关键字传参
- 字典关键字传参
形参:
把调用函数的实参拿到(接收实参)
形参的定义方式有四种:
- 位置形参
- *元组形参(接收多余的位置传参)
- 命名关键字形参(强制必须使用关键字传参)
- ** 字典形参(接收多余的关键字传参)
函数的缺省参数 default argument
def fx(a, b=0, c=100):
pass
全局变量 和 局部变量
在函数内赋值语句
变量 = 表达式
day10
globals() / locals()函数:
- globals() 返回当前全局作用域内变量的字典
- locals() 返回当前局部作用域内变量的字典
示例见:
# globals_locals.py
a = 1
b = 2
c = 3
def fn(c, d):
e = 300
# 此处有几个局部变量
print("locals() 返回:", locals())
print("------------------------")
print("globals()返回:", globals())
print("局部变量c的值是:", c)
print("全局的变量的c的值是:", globals()['c'])
fn(100, 200)
print('===========================')
print("全局的 globals() 返回: ", globals())
函数变量
函数名是变量,它在def 语句创建函数时绑定一个函数
示例见:
def fa():
print("hello world")
f1 = fa # <<<---这里没有括号,f1 变量绑变的是函数
f1() # 调用 fa绑定的函数
fa() # 调用 fa绑定的函数
# 此示例示意函数变量的赋值
def f1():
print("hello")
def f2():
print("world")
f1, f2 = f2, f1
f1() # world
f2() # hello
一个函数 可以作为另一个函数的实参传递
示例1:
def f1():
print("f1被调用")
def f2():
print("f2被调用")
def fx(fn):
print(fn)
fn() # 此时这是调用什么呢?
fx(f1)
fx(f2)
示例1:
def goodbye(L):
for x in L:
print("再见:", x)
def hello(L):
for x in L:
print("你好:", x)
def operator(fn, L):
fn(L)
operator(hello, ['Tom', 'Jerry', 'Spike'])
#你好:Tom
#你好:Jerry
#你好:Spike
看懂如下代码:
def myinput(fn):
L=[5,3,1,9,7]
return fn(L)
print(myinput(max)) #9
print(myinput(min)) #1
print(myinput(sum)) #25
print(myinput(len)) #5
函数可以作为另一个函数的返回值
示例见:
def fx():
return max
fn = fx()
print(fn([1, 3, 5, 7]))
函数的嵌套定义
函数嵌套定义是指一个函数里用def语句来创建其它的函数的情况
示例:
def fn_outter():
print("fn_outter被调用")
def fn_inner():
print("fn_inner被调用")
fn_inner()
fn_inner()
print("fn_outter调用结束")
fn_outter()
#fn_outter被调用
#fn_inner被调用
#fn_inner被调用
#fn_outter调用结束
示例2:
# return_function2.py
def get_op():
s = input("请输入您要做的操作: ")
if s == '求最大':
return max
elif s == '求最小':
return min
elif s == '求和':
return sum
L = [2, 4, 6, 8, 10]
print(L)
f = get_op()
print(f(L))
练习:
写一个计算公式的解释执行器
已知有如下一些函数:
def myadd(x, y):
return x + y
def mysub(x, y):
return x - y
def mymul(x, y):
return x * y
写一个函数,传入字符串,返回相应的函数
def get_op(s):
# 此函数根据字符串来返回相应的函数.
# 如果传入字符串"加" 则返回myadd函数
# .... '乘',则返回mymul函数
... 此处自己实现
主程序如下:
while True:
s = input("请输入计算公式: ")# 10 加 20
L = s.split()
a = int(L[0])
b = int(L[2])
fn = get_op(L[1])
print("结果是:", fn(a, b)) # 30
def get_op(s):
def myadd(x, y):
return x + y
def mysub(x, y):
return x - y
def mymul(x, y):
return x * y
# 此函数根据字符串来返回相应的函数.
# 如果传入字符串"加" 则返回myadd函数
# .... '乘',则返回mymul函数
if s == '加' or s == '+':
return myadd
elif s == '乘' or s == '*':
return mymul
elif s == '减' or s == '-':
return mysub
while True:
s = input("请输入计算公式: ") # 10 加 20
L = s.split()
a = int(L[0])
b = int(L[2])
fn = get_op(L[1])
print("结果是:", fn(a, b)) # 30
python 的作用域
作用域也叫名字空间,是访问变量时查找变量名的范围空间
python的四个作用域:
作用域 英文解释 英文缩写
局部作用域(函数内) Local(function) L
外部嵌套函数作用域 Enclosing function locals E
函数定义所在模块(文件)作用域 Global(module) G
Python内建模块的作用域 Builtin(Python) B
示例见:
v = 100
def f1():
v = 200
print("f1.v =", v)
def f2():
v = 300
print('f2.v =', v)
f2()
f1()
print('v =', v)
#f1.v 200
#f2.v 300
#v= 100
变量名的查找规则
在变量访问时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内建变量
即:
L ----> E ----> G ----> B
在默认的情况下,变量名赋值会创建或者改变当前作用域的变量
global 语句
作用:
1. 告诉解释执行器 global 语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,也称作全局变量
2. 全局声明(global)将赋值语句操作的变量映射到模块文件内部的作用域
语法:
global 变量1, 变量2, ...
示例见:
v = 100
def fn():
global v # 声明v是全局,此时不允许在此作用域存在v
v = 200 # 想让此语句去修改全局作用域内的变量v
print('fn内的v =', v)
fn() #fn内的v =200
print("v=", v) # v = 200 #不加global,v=100
示例2:
# global2.py
# 2. 全局变量在函数内部不经过声明就可以直接访问
# (变量已经存在并关联一个对象)
def fn():
n = v
print(n)
v = 100
fn()
#100
示例3:
# 3. 不能先声明局部变量,再用global声明为全局变量,
# 此做法不附合规则
v = 100
def fn():
v = 200 # 创建局部变量
global v # 此时至少是警告(不建议这样写)
v = 300
print(v)
fn()
print('v=', v)
示例4:
# 4. global变量列表里的变量名不能出现在此作用域的形
# 参列表里
v = 100
def fx(v):
# global v # 此处会出错 SyntaxError: name 'v' is parameter and global
print(v) # 请问打印多少?
fx(200) #200
print('v=', v) # v=100
说明:
1. 全局变量如果要在函数内部被赋值,则必须经过全局声明(否则会被认为是创建局部变量)
2. 全局变量在函数内部不经过声明就可以直接访问(变量已经存在并关联一个对象)
3. 不能先声明局部变量,再用global声明为全局变量,此做法不附合规则
4. global变量列表里的变量名不能出现在此作用域的形参列表里
练习:
写一个函数叫hello(name),部分代码如下:
count = 0
def hello(name):
print('你好', name)
... 此处代码省略,需要同学们自己填写
... 此处代码需要改变全局变量来记录此函数曾经被调用过多少次.
hello('小张')
hello('小李')
print('hello 函数被调用', count, '次') # 2次
count = 0 # 此变量用于记录hello函数调用的次数
def hello(name):
print('你好', name)
global count
count += 1 # count = count + 1
hello('小张')
hello('小李')
print('hello 函数被调用', count, '次') # 2次
nonlocal 语句
作用:
告诉解释执行器,nonlocal声明的变量不是局部变量,也不是全局变量,它是外部嵌套函数内的变量
语法:
nonlocal 变量名1, 变量名2, ....
示例见:
# nonlocal.py
# 此示例示意nonlocal 声明语句的用法
var = 100
def outter():
var = 200
print("outter内的var=", var)
def inner():
nonlocal var
var = 300
print("inner内的var=", var)
inner()
print("outter结束时的var=", var)
outter()
print('全局的var=', var)
#outter内的var=200
#inner内的var=300
#outter内的var=300
#全局的var=100
#++++++++++++++++++++++++++++++++++++++++++++++
#把nonlocal var改成global var
#var = 100
#def outter():
# var = 200
# print("outter内的var=", var)
#
# def inner():
# global var
# var = 300
# print("inner内的var=", var)
# inner()
# print("outter结束时的var=", var)
#outter()
#print('全局的var=', var)
#outter内的var=200
#inner内的var=300
#outter内的var=200
#全局的var=300
示例2:
# nonlocal2.py
# 3. 当有两层或两层以上函数嵌套时,访问nonlocal变量只
# 对最近的一层变量进行操作
v = 100
def f1():
v = 200
def f2():
v = 300
def f3():
nonlocal v
v = 400
print('fv3.v=', v)
f3()
print("f2.v =", v)
f2()
print('f1.v=', v)
f1()
#fv3.v=400
#f2.v =400
#f1.v=200
示例3:
# 4. nonlocal语句的变量列表里的变量名,不能出
# 现在此函数的参数列表中
var = 100
def outter():
var = 200
print("outter内的var=", var)
def inner(var):
nonlocal var # 此处会出错
var = 300
print("inner内的var=", var)
inner(3)
print("outter结束时的var=", var)
outter()
print('全局的var=', var)
说明:
1. nonlocal 语句只能在被嵌套的函数内部进行使用
2. 访问nonlocal变量将对外部嵌套函数作用域内的变量进行操作
3. 当有两层或两层以上函数嵌套时,访问nonlocal变量只对最近的一层变量进行操作
4. nonlocal语句的变量列表里的变量名,不能出现在此函数的参数列表中
def 语句:
作用:
创建函数
lambda 表达式(又称匿名函数)
作用:
创建一个匿名函数对象
同 def 类似,但不提供函数名
格式:
lambda : 表达式
示例见:
def myadd(x, y):
return x + y
myadd = lambda x, y: x + y
print("20 + 30 = ", myadd(20, 30)) # 50
print("40 + 50 = ", myadd(40, 50)) # 90
说明:
1. lambda 只是一个表达式,它用来创建一个函数对象
2. 当lambda表达式调用时,先执行冒号(:)后的表达式,并返回表达式的结果的引用关系
3. lambda 表达式创建的函数只能包含一条表达式
4. lambda 比函数简单且可以随时创建和销毁,有利于减少程序的偶合度
练习:
1. 写一个lambda 表达式,判断这个数的2次方+1是否能被5整除,如果能被整除返回True, 否则返回False
例:
fa = lambda x: .....
print(fa(2)) # True
print(fa(4)) # False
fa = lambda x: (x ** 2 + 1) % 5 == 0
print(fa(2)) # True
print(fa(4)) # False
2. 写一个lambda表达式,求两个变量的最大值
例如:
def mymax(x, y):
...
mymax = lambda ...
print(mymax(100, 200)) # 200
# def mymax(x, y):
# return x if x > y else y
# if x > y:
# return x
# return y
# mymax = lambda x, y: x if x > y else y
mymax = lambda x, y: max(x, y)
print(mymax(100, 200)) # 200
eval() / exec() 函数
eval(source, globals=None, local=None) 把一个字符串 srouce 当成一个表达式来执行,返回表达式执行的结果
exec(source, globals=None, locals=None) 把一个字符串source 当成程序来执行
eval示例见:
# eval.py
x = 100
y = 200
a = eval('x + y')
print(a) # 300
a = eval('x + y', {'x': 1, 'y': 2})
print(a) # 3
a = eval('x + y',
{'x': 1, 'y': 2},
{'x': 10, 'y': 20})
print(a) # 30
a = eval('x + y',
{'x': 1, 'y': 2},
{'x': 10})
print(a) # 12
# eval2.py
while True:
s = input("请输入表达式: ")
if not s:
break
a = eval(s)
print(a)
exec 示例见:
# exec.py
s = '''print("hello world!")
x = 100
x += 200
print('x=', x)
'''
exec(s) # 把s当成程序来执行
练习:
1. 给出一个整数n,写一个函数myfac来计算n!(n的阶乘)
n! = 1 * 2 * 3 * 4 * ..... * n
如:
print(myfac(5)) # 120
def myfac(n):
m = 1
for x in range(2, n + 1):
m *= x
return m
print(myfac(5)) # 120
2. 给出一个整数n,写一个函数计算myfn(n):
1 + 2**2 + 3**3 + .... + n**n的和
如:
print(myfn(10)) # ???
# def myfn(n):
# s = 0
# for i in range(1, n + 1):
# s += i ** i
# return s
def myfn(n):
return sum(map(lambda i: i ** i,
range(1, n + 1)
)
)
print(myfn(10)) # 10405071317
3. 完全数:
1 + 2 + 3 = 6 (6为完全数)
1,2,3都为6的因数(因数是能被一个数x整除的整数为y,则y为x的因数)
1 x 6 = 6
2 x 3 = 6
完全数是指除自身以外的所有因数相加之和等于自身的数
求 4~5个完全数并打印出来
答案:
6
28
496
......
def is_perfect_number(n):
# 此函数判断n是否是完全数,
# 如果是则返回True,否则返回False
L = [] # 此列表用于存放 所有的因数
for x in range(1, n):
if n % x == 0: # 整除了.则说明x为n的因数
L.append(x)
return sum(L) == n # 如果因数之和等于n则返回True
def print_number(): # 此函数用于打印所有的完全数
i = 1
while True:
if is_perfect_number(i):
print(i) # 打印这个完全数
i += 1
print_number() # 开始计算
4 实现带有界面的学生信息管理系统
程序启动时先弹出操作菜单:
+-------------------------+
| 1) 添加学生信息 |
| 2) 显示学生信息 |
| 3) 删除学生信息 |
| 4) 修改学生成绩 |
| q) 退出 |
+-------------------------+
请选择: 1
要求 :
每个选择都要有一个函数来实现
def input_student():
L = [] # 创建一个容器准备放入
while True:
name = input('请输入姓名: ')
if not name: # 如果名字为空,结束输入操作
break
age = int(input("请输入年龄: "))
score = int(input("请输入成绩: "))
d = {} # 每次都会执行{} 来创建新的字典
d['name'] = name
d['age'] = age
d['score'] = score
L.append(d)
return L
def output_student(lst):
# 打印表格
print("+---------------+----------+----------+")
print("| name | age | score |")
print("+---------------+----------+----------+")
for d in lst:
n = d['name'].center(15)
a = str(d['age']).center(10)
s = str(d['score']).center(10)
print("|%s|%s|%s|" % (n, a, s))
print("+---------------+----------+----------+")
def show_menu():
print('+-------------------------+')
print('| 1) 添加学生信息 |')
print('| 2) 显示学生信息 |')
print('| 3) 删除学生信息 |')
print('| 4) 修改学生成绩 |')
print('| q) 退出 |')
print('+-------------------------+')
def main():
docs = [] # 用于存放学生信息的空列表
while True:
show_menu()
s = input("请选择: ")
if s == '1':
docs += input_student()
elif s == '2':
output_student(docs)
elif s == '3':
print("开始删除")
elif s == '4':
print("开始修改成绩")
elif s == 'q':
break
main()