python 的函数值传递和作用域 (例子)
1.python 的函数格式:defFuncName([arg1,arg2,..]):
func_suite
def: def 是函数的关键字
FuncName: 实际也是变量, 它指向函数对象, 在函数定义时被赋值, 根据习惯, 这里我们成为函数名
():() 是函数运算符, 引用函数时, 用函数名 +() 引用, 如: FuncName()
[arg1,arg2,..]: 这个是函数体的参数, 当为空时, 我们称这个函数为无参函数, 相对应的就是有参函数, python 的参数传递很强大, 可以是位置参数一一对应, 也可以默认参数赋值, 还可以传递字典等
":" : python 的语句都必须以 : 结尾
func_suite: 这个是函数体的内容, 可以用 "pass" 进行占位, 还可以嵌套函数等
需要注意的是, 每个函数结束后都必须返回值, 如果没有用 return 关键字明确指明, 那么默认返回 None
例子:In[2]:defhello():
...:print"hello"
...:
In[3]:a=hello()
hello
In[4]:printa
None
2. 参数传递:
<1 > 普通的从左往右匹配的参数传递deff1(x,y):
print"x:%d y:%d"%(x,y)
In[38]:m=1
In[39]:n=2
In[40]:f1(m,n)
x:1y:2
In[41]:f1(n,m)
x:2y:1
这种方式传参个数必须匹配, 否则报错
<2 > 设置默认参数In[42]:deff2(x=1,y):
...:print"x:%d y:%d"%(x,y)
File"",line1
deff2(x=1,y):
SyntaxError:non-defaultargument followsdefaultargument
In[43]:deff2(y,x=1):
...:print"x:%d y:%d"%(x,y)
In[45]:n=99
In[46]:m=6
In[47]:f2(n)
x:1y:99
In[48]:f2(n,m)
x:6y:99
(1) 默认参数要写在位置参数后面, 否则报错
(2) 传递参数时, 可以不传递默认有值的参数, 但是当传递了对应参数, 默认值会被覆盖掉
<3>1 个 *, 传递任意个数参数 (非键值对), 函数收集为列表In[53]:deff3(x,*y):
...:printx,y
...:
In[54]:n=1;m=2
In[55]:f3(n,m,4,5,6)
1(2,4,5,6)
带 * 的参数也要放在位置参数后面, 位置参数匹配完后, 剩下的才会收集为列表并赋值给 y 这个变量
<4>2 个 *, 传递任意个键值对参数, 收集为字典In[85]:deff4(x,**y):
...:printx,y
...:
In[86]:f4(1,n=2,a=4,b=2)
1{a:4,b:2,n:2}
3.python 的作用域 (LEGB), 参考: https://segmentfault.com/a/1190000000640834
简而言之, LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> builtins
locals 是函数内的名字空间, 包括局部变量和形参
enclosing 外部嵌套函数的名字空间 (闭包中常见)
globals 全局变量, 函数定义所在模块的名字空间
builtins 内置模块的名字空间
所以, 在 Python 中检索一个变量的时候, 优先回到 locals 里面来检索, 检索不到的情况下会检索 enclosing ,enclosing 没有则到 globals 全局变量里面检索, 最后是到 builtins 里面来检索
例子:[root@cqhdtest python_learn]#./getvalue.py
ExGyEz
LxGyEz
[root@cqhdtest python_learn]#cat getvalue.py
#!/usr/local/anaconda2/bin/python
x=Gx
y=Gy
z=Gz
deff1(x,y,z):
x=Ex
z=Ez
printx,y,z
deff2(x,y,z):
x=Lx
printx,y,z
f2(x,y,z)
f1(x,y,z)
当调用 f1 函数时, 此时 f1 中的 print 语句会去寻找 x,y,z 变量的值, 它从当前作用域开始找, x,z 都在本域有值, 所以 x=Ex,z=Ez,y 没有值, 所以它向外去 globals 作用域找, 发现 y=Gy, 所以第一行输出为 "Ex Gy Ez", 程序继续执行, 调用 f2 函数, f2 的 print 也查找 x,y,z 的变量的值, 首先在 local 域找, 发现 x="Lx",y 在 local 找不到, 于是去 enclosing 域找, 发现也没有, 于是找 Global 域, 所以 y=Gy,z 同理, 在 enclosing 域找到了, 便停止搜索, 于是 z=Ez, 所以第二行输出为 "Lx Gy Ez"
如果我们想在函数内对全局变量进行修改, 则可以使用 global 关键字
global: 告诉函数, 使用全局变量作为当前变量
例子:[root@cqhdtest python_learn]#./global.py
Gx
Ex
[root@cqhdtest python_learn]#catglobal.py
#!/usr/local/anaconda2/bin/python
x=Gx
deff1():
x=Ex
deff2():
globalx
x=Ex
f1()
printx
f2()
printx
函数 f1 中的 x 是本地变量, 当 f1 执行完后 x 的值也被销毁
函数 f2 中的 x 使用全局变量, 所以当 x 被改变后, print 的值也变了
来源: http://www.bubuko.com/infodetail-2533002.html