1.自定义函数
- 给函数编写文档:
def function(x): "This is function document test." #注意这里没有加入#号,这是函数内的写作方式。 pass
#注意下面的语句是function而不是function()。前者表示函数本身,后者表示函数的使用。 print(function.__doc__) help(function)
- 所有的函数都有返回值。函数return后什么都没有,或没有return,函数返回None。不要让None的返回值给你带来麻烦。
2.函数参数
- 编写代码时,为了确保参数的正确性。应该在参数输入不对时以显而易见的方式失败。为此,通常使用assert断言和raise异常。
- 参数为不可变参数:string、数、tuple,函数不修改外部变量
N=456 def test(n): n=123 test(N) #这相当于函数内部变量先建立内存n=N,然后再处理n print(N) #456
- 参数为可变参数:list、dict,函数修改。
list1=[1,"a",2] def test(l1): l1.append(123) test(list1) #由于是可变参数,l1=list1只是建立了指针,并没有为数据重新建立内存。 print(list1) #[1, 'a', 2, 123]
-
函数参数可以分为位置参数和关键字参数。
- 位置参数具有顺序依赖性
- 关键字参数若以keyword形式传递,可以打乱顺序。function(key2=...,key1=...)
- 参数的收集,输入的参数以什么形式存放:
#参数收集:*args以元组形式存放,**kwargs以字典形式存放 def func(*args,**kwargs): print(args) print(kwargs) func(1,2,3,"a","b",key1="name",key2="age",key3="sex") #(1, 2, 3, 'a', 'b') #{'key1': 'name', 'key2': 'age', 'key3': 'sex'}
-
参数的分配,如果不是一一对应的输入参数,而是输入一个整体,输入数据如何分配:
#如果以序列形式分配,要加上* def test1(a,b,c,d): print(a,b,c,d) List1=[1,"a",2,"b"] Tuple1=(4,3,2,1) test1(*List1) #1 a 2 b test1(*Tuple1) #4 3 2 1 #如果以字典形式分配,要加上**,且key相同 def test2(m,n): print(m,n) Dict1={"m":"name","n":"age"} test2(**Dict1) #name age
3.函数的作用域和嵌套:
- global声明全局变量,nonlocal声明非全局的上一层变量:
#以下例子只是说明问题 , 实际应用中务必慎用全局变量。 x,y,z=1,2,3 def testA(): global x #全局变量,指向最外层 x,y,z=10,20,30 #全局x重新赋值 print("first:",x,y,z) # first: 10 20 30 def testB(): global y #指向最外层,不是上一层 y+=10 #所以y不是上一层的10,而是最外部的2 x=20 #第二层没有声明x,所以x是局部 print("second:",x,y,z) # second: 20 12 30 def testC(): nonlocal x x+=10 global z print("third:",x,y,z) # third: 30 12 3 testC() print("second2:",x,y,z) # second2: 30 12 30 testB() print(testA(),x,y,z) # None 10 12 3
- 函数的嵌套:可以在函数中定义函数,注意嵌套时return的是函数的运行(带括号)还是函数本体(不带括号)
def test1(): def test2(): print("test2 in test1") return test2() #返回的是函数test2()的运行 test1() # test2 in test1 def test3(): def test4(): print("test4 in test3") return test4 #返回的是函数test4的本体 test3()() # test4 in test3,其中的test3()就相当于test4,所以需要加()才可以运行