函数
(一)函数参数类型
不可变类型参数:整数、字符串、元组
1、传递不可变类型参数,不会影响参数本身
def hanshu(a):
a += 3
print('函数内部:a=', a)
x = 10
hanshu(x)
print('x=', x)
调用时,相当于x调用了一个副本,对其本身无影响
2、传递可变类型参数,会影响参数本身
def hanshu(a):
a.append(3)
print(a)
x = [1, 2]
hanshu(x)
print(x)
(二) 命名空间
命名空间指的是保存程序中的变量名和值的地方。命名空间的本质是一个字典,用来记录变量名称和值。
命名空间一共分为3种:局部、全局、内置
1、命名空间访问
local()函数–局部
globals()函数–全局
a = 3
b = 4
def hanshu(x):
c = 5
d = 6
print(locals())
print(globals())
hanshu(6)
2、命名空间加载顺序
内置->全局->局部
(三)作用域
作用域:变量在程序中的可应用范围
local(函数内部)局部作用域
enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)
global(模块全局)全局作用域
built-in(内建)内建作用局(指的是builtins.py模块)
a = 3
b = 30
c = 300
def hsw():
a = 4
b = 40
def hsn():
a = 5
# 在第一处能够找到这个变量名的地方停下来。
print(a) # L local 优先使用本地的
print(b) # E enclosing 本地没有找嵌套作用域
print(c) # G global 全局作用域
print(__name__) # B built-in 找内置作用域
# 如果没有找到,就报错
# print(xiaogou)
hsn()
hsw()
python内层作用域访问外层作用域时的顺序:
本地作用域(L)之后是上一层结构中def后者lambda的本地作用域(E),之后是全局作用域(G)最后是内置作用域(B)。并且在第一处能够找到这个变量名的地方停下来。如果变量名在整个的搜索过程中都没有找到,python就会出错。
(由里向外找)
(四)全局变量和局部变量
在函数中定义的变量称为局部变量,只在函数内部生效
在函数外部定义的变量称为全局变量,全局变量的作用域时从定义开始到整个程序结束
1、全局变量是不可变数据类型,函数无法修改全局变量的值
def hanshu(a):
a=[1, 2] # a没有用到
b = [3, 4] # 重新定义了一个列表
hanshu(b)
print(b)
2、全局变量是可变数据类型,函数可以修改全局变量的值
def hanshu(a):
a['name'] = 'zhang'
print(a)
x = {'age': '20'}
hanshu(x)
print(x)
(五)global和nonlocal关键字
1、global关键字可以将局部变量变成一个全局变量
def hanshu():
global a # global关键字将局部变量变成一个全局变量
a += 10
print('函数内部:', a)
a = 20
hanshu()
print('函数外部:', a)
2、nonlocal关键字可以修改外层(非全局)变量
def hsw():
a = 9
def hsn():
nonlocal a # 不是本部,与global作用类似
a = 98
print('我是内部', a)
hsn()
print('我是外部', a)
hsw()
(六)内置函数
1、abs()函数
求数字的绝对值
a = -1
b = 2
print(abs(a))
print(abs(b))
2、max()函数
max()求序列的最大值
(1)简单实用max()函数
a = [1, 3, 2, 5, 4]
x = max(a)
print(x)
(2)使用key关键字
a = [-1, -3, -2, -5, -4]
b = max(a, key=abs) # 先将列表进行绝对值,然后再进行求最大值
print(b)
(3)根据name和price返回最大的信息
通过比较ASCII码
a = [{'name': 'zhang', 'age': 19}, {'name': 'li', 'age': 29}, {'name': 'wang', 'age': 8}]
def getAge(x):
return x['age']
b = max(a,key=getAge)
print(b)
a = [{'name': 'a', 'age': 19}, {'name': 'b', 'age': 29}, {'name': 'C', 'age': 8}]
def getAge(x):
return x['name']
b = max(a,key=getAge) # 通过ASCII码进行比较
print(b)
3、map()函数
函数会依次作用在可迭代内容的每一个元素上进行计算,然后返回一个新的可迭代内容
def hs(x):
return x*x
a = [1, 2, 3]
b = map(hs, a)
print(b)
c = list(b)
print(c)
4、filter()函数
filter()函数:过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新对象
接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断
然后返回True或False,最后将返回True的元素放到新列表中
def gl(a):
if a%3==0 or a%7==0:
return True
else:
return False
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = filter(gl, a)
print(b)
print(list(b))
5、zip()函数
zip():将对象中对应的元素打包成一个元组
返回的列表与长度最短的相同
a = [1, 2, 3]
b = ['a', 'b', 'c']
c = zip(a, b)
print(c)
for x in c:
print(x)
(七)匿名函数
匿名函数
语法:变量名 = lambda 参数:表达式(block)
参数:以逗号分隔的变量表达式形式,也就是和位置参数
表达式:不能包含循环、return、可以包含if…else…
hs = lambda x,y:x+y
b = hs(2, 3)
print(b)
x = lambda a, b: a if a > b else b
y = x(2, 3)
print(y)
a = [{'name': 'a', 'age': 19}, {'name': 'b', 'age': 29}, {'name': 'C', 'age': 8}]
hs = max(a, key=lambda a : a['age'])
print(hs)
(八)嵌套作用域和lambda
lambda表达式也会产生一个新的局部作用域。在def定义的函数中嵌套lambda表达式,lambda表达式能够看到所有的def定义的函数中可用的变量
def hehe():
a = []
for i in range(3):
b = lambda y: y*i
a.append(b)
return a
z = hehe()
i = 9
print(z[0](2))
print(z[1](2))
print(z[2](2))
答案都是4.
因为嵌套作用域中的变量在嵌套的函数被调用时才进行查找,所以实际上记住的是同样的值(在最后一次循环时循环变量的值)。也就是i取值为2。
稍作修改:
def hehe():
a = []
for i in range(3):
b = lambda y, i=i: y*i
a.append(b)
return a
z = hehe() # 调用时,执行for i in range(3) 此时i=2,已被保留 并且最终返回三个lambda
print(z[0](2))
print(z[1](2))
print(z[2](2))