Python函数 - littleboy12580/learning_python GitHub Wiki
函数
作用域
- 作用域可以分为本地作用域与全局作用域
- 内嵌的模块是全局作用域
- 全局作用域的作用范围仅限于单个文件
- 在原处改变对象并不会把变量划分为本地变量,只有对变量名赋值才可以;例如L.append(X)语句不会将L划分为本地变量,而L = X却可以。
变量的LEGB作用域查找原则
当引用一个变量时,Python会按以下顺序依次进行查找:首先是在本地变量中查找,然后在任意上层函数作用域里查找,再然后是全局作用域,最后则是在内置作用域查找。
global语句
通过global声明可以将一个变量变为全局变量
X = 88
def func():
global X
X = 99
func()
print(X)
此时X值为99
文件间的调用修改
在导入模块之后,被导入模块的全局变量属性是可能会被修改的,如下例:
#first.py
X=99
#second.py
import first
print(first.X)
first.X = 88
这种文件依赖性过强的情况会导致代码不灵活,因此在文件间通信最好的办法是通过调用函数,传递参数,然后得到其返回值,如下例:
#first.py
X=99
def setX(new):
global X
X = new
#second.py
import first
first.setX(88)
参数的引用
python中函数参数是通过赋值传递的,函数中的参数名可以在调用时通过变量实现共享对象;因此函数中的可变对象参数的原处修改是可以影响到调用者的,就相当于C语言里的指针传递一样;而不可变对象参数即使进行了原处修改也不会影响到调用者,相当于值传递。
参数的匹配扩展
参数收集
参数收集有两种,和*
*在函数定义中表示在元组中收集不匹配的位置参数
def f(*args): print(args)
f(1)
f(1,2,3,4)
上面代码最后输出的是(1,)和(1,2,3,4)
**在函数定义中只对关键字参数有效,它将关键字参数传递给一个新的字典
def f(**args): print(args)
f(a=1,b=2)
上面代码最后输出的是{'a':1,'b':2}
函数头部能够混合一般参数,*参数以及**参数来实现更加灵活的调用方式
def f(a,*pargs,**kargs): print(a,pargs,kargs)
f(1,2,3,x=1,y=2)
上面代码最后输出的是 1 (2,3) {'y':2,'x':1}
解包参数
与参数收集相对应,在调用参数的时候也能够使用*和**语法,此时是将传入的参数解包成不同的参数
def func(a,b,c,d): print(a,b,c,d)
args = (1,2,3,4)
func(*args)
上面代码结果为1 2 3 4
args = {'a':1,'b':2,'c':3,'d':4}
func(**args)
上面代码结果为 1 2 3 4
func(*(1,2),**{'d':4,'c':4})
func(1,c=3,*(2,),**{'d':4})
上面代码结果为1 2 4 4和1 2 3 4
参数排序规则
在一个函数头部,keyword-only参数必须编写在**args之前,*args之后
lambda表达式
lambda表达式创建了一个之后能够调用的函数,但是它返回了一个函数而不是将这个函数赋值给了一个变量名。
f=lambda x,y,z:x+y+z
f(2,3,4)
默认参数也能够在lambda参数中使用
x=(lambda a="fee",b="fie",c="foe":a+b+c)
x("wee")
输出为'weefiefoe'
生成器函数
- 送回一个值并随后从其退出的地方继续的函数叫做生成器函数;它通过yield表达式來挂起函数并向调用者发送回一个值,但是保留足够的状态以使得函数能够从它离开的地方继续。
- 生成器函数返回的是生成器对象,他支持迭代器协议,存在__next__()方法
def gensquares(N):
for i in range(N):
yield i ** 2
for i in gensquares(5):
print(i,end=' : ')
最后的输出为 0 : 1 : 4 : 9 : 16 :
- 生成器表达式:与列表解析类似不过是括在圆括号中而不是方括号中
(x ** 2 for x in range(4))
返回的是一个可迭代对象而不是列表
-
生成器函数与生成器表达式均支持自动迭代和手动迭代,手动迭代需要使用iter()函数来启动迭代,然后使用next()进行迭代
-
生成器是单迭代对象
解析表达式
python3.0中可用的4种解析表达式形式:列表解析,生成器表达式,集合解析以及字典解析
- 列表解析
[x * x for x in range(10)]
- 生成器表达式
(x * x for x in range(10))
- 集合解析
{x * x for x in range(10)}
- 字典解析
{x:x * x for x in range(10)}