1.python 的函数格式:
- def FuncName([arg1,arg2,..]):
- func_suite
def: def 是函数的关键字
FuncName: 实际也是变量, 它指向函数对象, 在函数定义时被赋值, 根据习惯, 这里我们成为函数名
():() 是函数运算符, 引用函数时, 用函数名 +() 引用, 如: FuncName()
[arg1,arg2,..]: 这个是函数体的参数, 当为空时, 我们称这个函数为无参函数, 相对应的就是有参函数, python 的参数传递很强大, 可以是位置参数一一对应, 也可以默认参数赋值, 还可以传递字典等
":" : python 的语句都必须以 : 结尾
func_suite: 这个是函数体的内容, 可以用 "pass" 进行占位, 还可以嵌套函数等
需要注意的是, 每个函数结束后都必须返回值, 如果没有用 return 关键字明确指明, 那么默认返回 None
例子:
- In [2]: def hello():
- ...: print "hello"
- ...:
- In [3]: a=hello()
- hello
- In [4]: print a
- None
2. 参数传递:
<1 > 普通的从左往右匹配的参数传递
- def f1(x,y):
- print "x:%d y:%d" %(x,y)
- In [38]: m=1
- In [39]: n=2
- In [40]: f1(m,n)
- x:1 y:2
- In [41]: f1(n,m)
- x:2 y:1
这种方式传参个数必须匹配, 否则报错
<2 > 设置默认参数
- In [42]: def f2(x=1,y):
- ...: print "x:%d y:%d" %(x,y)
- File "<ipython-input-42-52965f3ab864>", line 1
- def f2(x=1,y):
- SyntaxError: non-default argument follows default argument
- In [43]: def f2(y,x=1):
- ...: print "x:%d y:%d" %(x,y)
- In [45]: n=99
- In [46]: m=6
- In [47]: f2(n)
- x:1 y:99
- In [48]: f2(n,m)
- x:6 y:99
(1) 默认参数要写在位置参数后面, 否则报错
(2) 传递参数时, 可以不传递默认有值的参数, 但是当传递了对应参数, 默认值会被覆盖掉
<3>1 个 *, 传递任意个数参数 (非键值对), 函数收集为列表
- In [53]: def f3(x,*y):
- ...: print x,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]: def f4(x,**y):
- ...: print x,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
- Ex Gy Ez
- Lx Gy Ez
- [root@cqhdtest python_learn]# cat getvalue.py
- #!/usr/local/anaconda2/bin/python
- x=Gx
- y=Gy
- z=Gz
- def f1(x,y,z):
- x=Ex
- z=Ez
- print x,y,z
- def f2(x,y,z):
- x=Lx
- print x,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]# cat global.py
- #!/usr/local/anaconda2/bin/python
- x=Gx
- def f1():
- x=Ex
- def f2():
- global x
- x=Ex
- f1()
- print x
- f2()
- print x
函数 f1 中的 x 是本地变量, 当 f1 执行完后 x 的值也被销毁
函数 f2 中的 x 使用全局变量, 所以当 x 被改变后, print 的值也变了
来源: http://www.bubuko.com/infodetail-2533002.html