函数(参数,作用域,返回函数,匿名函数,偏函数)

函数参数:

python 中的函数参数类型有 必须参数,关键字参数,默认参数,可变参数,组合参数

必须参数 

即形参和实参按照顺序一一对应

关键字参数 

函数调用使用关键字确定传入的参数值,允许实参和形参的顺序不一致,因为 python 解释器能够用参数名匹配参数值

代码:

 1 #!/usr/bin/python3
 2 
 3 def personinfo(age, name):
 4     print('年龄:', age)
 5     print('名称:', name)
 6     return
 7 
 8 personinfo(21, '小萌')
 9 print('-------------------')
10 personinfo(name = '小萌', age = 21)
11 print('-------------------')
12 personinfo(age = 21, name = '小萌')
View Code

默认参数

和 c++ 中一致

若要更改某一个默认参数值,又不想传入其它默认参数,且该默认参数的位置不是第一个,则可以通过参数名更改想要更改的默认参数值

代码:

 1 #!/usr/bin/python3
 2 
 3 def gel(a = 1, b = 2, c = 3):
 4     print(a, b, c)
 5     return
 6 
 7 gel()
 8 gel(10)
 9 gel(b = 10)
10 
11 '''
12 输出:
13 1 2 3
14 10 2 3
15 1 10 3
16 '''
View Code

可变参数

加了 * 的变量名会存放所有未命名的变量参数。如果变量参数再函数调用时没有指定参数,就是一个空元组。

代码:

 1 #!/usr/bin/python3
 2 
 3 def personinfo(arg, *var):
 4     print(arg)
 5     for indx in var:
 6         print(indx, end = ' ')
 7     print()
 8     return
 9 
10 personinfo(2, 'fd', 'aa')
View Code

用 ** 处理可变的关键字参数:

1 other = {'city' : 'beijing', 'hoby' : 'coding'}
2 
3 def personinfo(name, number, **kw):
4     print('名称:', name, '学号: ', number, '其它:', kw)
5 
6 personinfo('gel', 3366, city = other['city'], hoby = other['hoby'])
7 personinfo('gel', 3366, **other)#等效于上一条语句
View Code

组合参数

在编程中上述四种参数可以组合使用。注意定义参数的顺序是必须参数、默认参数、可变参数和关键字参数

代码:

 1 #!/usr/bin/python3
 2 
 3 def exp(p1, p2, df = 0, *vart, **kw):
 4     print(p1, p2, df, vart, kw)
 5 
 6 exp(1, 2)
 7 exp(1, 2, c = 3)
 8 exp(1, 2, 3, 'a', 'b')
 9 exp(1, 2, 3, 'abc', x = 9)
10 
11 # 输出:
12 # 1 2 0 () {}
13 # 1 2 0 () {'c': 3}
14 # 1 2 3 ('a', 'b') {}
15 # 1 2 3 ('abc',) {'x': 9}
View Code

变量作用域:

局部变量

和c++中一致,局部变量只能在定义它的函数中使用

全局变量

在函数体内可以直接使用全局变量,但在函数体中更改变量的值并不会更改全局变量的值。这是因为调用函数时创建了新的命名空间,它作用于该函数代码块。

代码:

 1 #!/usr/bin/python3
 2 
 3 x = 50
 4 def func(x):
 5     print('全局x=', x)
 6     x = 2
 7     print('局部x=', x)
 8 
 9 func(x)
10 print('全局x=', x)
11 
12 输出:
13 全局x= 50
14 局部x= 2
15 全局x= 50
View Code

注意:函数中使用某个变量时,如果该变量名既有全局变量又有局部变量,默认使用局部变量的值

要在函数中修改全局变量的值需要使用 global 关键字

代码:

 1 #!/usr/bin/python3
 2 
 3 x = 50
 4 def func():
 5     global x
 6     x = 2
 7     print('局部x=', x)
 8 
 9 func()
10 print('全局x=', x)
11 
12 # 输出:
13 # 局部x= 2
14 # 全局x= 2
View Code

注意:不能对形参使用 global 关键字

global 声明必须在函数中对应参数使用之前

返回函数:

代码:

 1 #!/usr/bin/python3
 2 
 3 def sum_late(*args):
 4     def calc_sum():
 5         ax = 0
 6         for n in args:
 7             ax += n
 8         return ax
 9     return calc_sum
10 
11 print(sum_late(1, 2, 3, 4))#输出对应的函数地址
12 calc_sum = sum_late(1, 2, 3, 4)
13 print(calc_sum())
14 
15 #每次调用都会返回一个新的函数,即使传入相同的参数也是如此
16 f1 = sum_late(1, 2, 3)
17 f2 = sum_late(1, 2, 3)
18 print('if f1 == f2?', f1 == f2)
19 
20 # 输出:
21 # <function sum_late.<locals>.calc_sum at 0x05804108>
22 # 10
23 # if f1 == f2? False
View Code

注意:每次调用都会返回一个新的函数,即使传入相同的参数也是如此

闭包

如果在一个内部函数里对外部函数(不是在全局作用域)的变量进行引用,内部函数就被认为是闭包

注意:返回闭包时,返回函数不要引用任何循环变量或后继会发生变化的变量,否则很容出错:

 1 #!/usr/bin/python3
 2 
 3 def count():
 4     fs = []
 5     for i in range(1, 4):
 6         def f():
 7             return i * i
 8         fs.append(f)
 9     return fs
10 
11 f1, f2, f3 = count()
12 print(f1())
13 print(f2())
14 print(f3())
15 
16 #输出并不是我们预期的1, 4, 9
17 # 输出:
18 # 9
19 # 9
20 # 9
View Code

显然,上面出错的原因是加入 fs 后的函数并没有立即离开 for 循环(i 的作用域),因此会收到 i 的后续影响。

要修改使其正确的话我们可以再套一个函数隔开 i 的作用域即可:

 1 #!/usr/bin/python3
 2 
 3 def count():
 4     def f(x):
 5         def g():
 6             return x * x
 7         return g
 8 
 9     fs = []
10     for i in range(1, 4):
11         fs.append(f(i))
12     return fs
13 
14 f1, f2, f3 = count()
15 print(f1())
16 print(f2())
17 print(f3())
18 
19 # 输出:
20 # 1
21 # 4
22 # 9
View Code

匿名函数:

lambda 函数拥有自己的命名空间,不能访问自有参数列表之外或全局命名空间的参数

lambda 函数的语法只包含一个语句

python 中 lambda 不能有 return 语句,但其实 : 后面部分即为返回值,:之前部分可以看作是参数,且可以只用默认值

两个数求和:

1 #!/usr/bin/python3
2 
3 sum = lambda x, y : x + y
4 print(sum(1, 2))
5 print(sum(2, 3))
6 # 输出:
7 # 3
8 # 5
View Code

和 filter 一起使用:

 1 def func(x):
 2     return x > 3
 3 
 4 l1 = [1, 2, 3, 4, 5]
 5 
 6 f_list = filter(func, l1)
 7 print([item for item in f_list])
 8 
 9 print([item for item in filter(lambda x : x > 3, l1)])
10 
11 # 输出:
12 # [4, 5]
13 # [4, 5]
View Code

python3 开始 filter 返回迭代器(之前是返回列表)

如果需要将迭代器改成列表可以:

filter_list = [item for item in a_file_object]

偏函数:

类似于 c++ bind 的一个东西:http://www.cnblogs.com/geloutingyu/p/8335230.html

 1 #!/usr/bin/python3
 2 
 3 from functools import partial
 4 
 5 def mod(n, m):
 6     return n % m
 7 
 8 mod_by_100 = partial(mod, 100)
 9 
10 print(mod(100, 7))
11 print(mod_by_100(7))
12 # 输出:
13 # 2
14 # 2
View Code
原文地址:https://www.cnblogs.com/geloutingyu/p/8728332.html