一.函数基础知识
函数是面向过程编程的最小单位,也是一种数据
目的就是封装方便以后复用
函数分自定义函数,内置函数(python官方),第三方函数(第三方库)
1 2 3 4 5 6 7 def function_name (parameters ): return result print (type (function_name))
<class 'function'>
def:用于声明一个函数,告诉 Python 这是一个函数的定义。
function_name:函数名,一个有效的标识符,规则和变量名一致。
parameters:形参,可以是0 ~ n 个,参数之间用逗号分隔。
函数体:定义函数执行的具体操作。
return:指定函数的返回值,没有则默认返回None。
return之后的代码不会执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def test (): print ('test' ) return 1 print ('test2' ) return print ('test3' ) return test() x = 10 x
test
10
1 2 3 4 5 6 7 8 9 10 11 12 def test (): print ('test' ) return 1 print ('test2' ) return print ('test3' ) return test() x = test()print (x)
test
test
1
二.函数调用
2.1 位置传参 1 2 3 4 5 6 7 8 def func (a,b ): print (a,b) return func(1 ,2 ) func(2 ,1 ) func(1 ,2 ,3 )
1 2
2 1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[21], line 8
6 func(1,2)
7 func(2,1)
----> 8 func(1,2,3)
TypeError: func() takes 2 positional arguments but 3 were given
1 2 3 4 def func (a,b ): print (a) func(1 ,2 )
1
2.2 关键词传参 1 2 3 4 5 6 7 8 9 def func (a,b,c ): print (a,b,c) func(b = 1 ,c = 2 ,a = 3 ) def func (a,b,c ): print (a,b,c) func(1 ,c = 2 ,b = 3 )
3 1 2
1 3 2
1 2 3 def func (a,b,c ): print (a,b,c) func(1 ,c = 3 ,2 )
Cell In[36], line 3
func(1,c = 3,2)
^
SyntaxError: positional argument follows keyword argument
2.3 参数默认值 1 2 3 4 5 6 7 8 def test (a, b = 2 , c = 1 ): print (a,b,c) return test(1 ) test(1 ,2 ,3 ) test(1 ,c = 3 ) test(1 ,None ,3 )
1 2 1
1 2 3
1 2 3
1 None 3
1 2 3 4 def test (a = 1 , b, c = 3 ): print (a,b,c) return
Cell In[46], line 2
def test(a = 1, b, c = 3):
^
SyntaxError: parameter without a default follows parameter with a default
2.4 可变位置参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def test (*args ): print (args) print (type (args)) print () return test(1 ,2 ,3 ) test() def test (a,*args ): print (a) print (args) print (type (args)) return test(1 ,2 )
(1, 2, 3)
<class 'tuple'>
()
<class 'tuple'>
1
(2,)
<class 'tuple'>
2.5 可变关键词参数(字典) 1 2 3 4 5 6 7 8 def test (a,**kwargs ): print (kwargs) print (type (kwargs)) for i in kwargs: print (i,kwargs[i]) test(1 ,b=2 ,c=3 )
{'b': 2, 'c': 3}
<class 'dict'>
b 2
c 3
两个可变参数的联合使用
实质是剩余参数传递,即普通形参传完后剩余的参数传递给可变参数
1 2 3 4 5 6 def test (a,*args,**kwargs ): print (a) print (args) print (kwargs) test(1 ,2 ,3 ,4 ,Name = 'clocky7' )
1
(2, 3, 4)
{'Name': 'clocky7'}
2.6 多参数解包 2.6.1 解包位置传参 1 2 3 4 5 6 def test (a,b,c ): print (a,b,c) x = (1 ,2 ,3 ) test(*x)
1 2 3
1 2 3 4 5 6 def test (a,b,c ): print (a,b,c) x = (1 ,2 ,3 ,4 ) test(*x)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[68], line 6
3 print(a,b,c)
5 x = (1,2,3,4)
----> 6 test(*x)
TypeError: test() takes 3 positional arguments but 4 were given
1 2 3 4 5 def test (a,b,c ): print (a,b,c) x = (1 ,2 ) test(*x)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[70], line 5
3 print(a,b,c)
4 x = (1,2)
----> 5 test(*x)
TypeError: test() missing 1 required positional argument: 'c'
2.6.2 解包关键字传参(字典) 1 2 3 4 def test (a,b,c ): print (a,b,c) x = {'a' :1 ,'c' :3 ,'b' :2 } test(**x)
1 2 3
注意 : * 本身不是参数,只是一个占位符
1 2 3 def test (a,*,b = 3 ): print (a,b) test(1 )
1 3
1 2 3 def test (a,*,b = 3 ): print (a,b) test(1 ,3 )
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[83], line 3
1 def test(a,*,b = 3):
2 print(a,b)
----> 3 test(1,3)
TypeError: test() takes 1 positional argument but 2 were given
1 2 3 4 def test (a,*,b = 3 ): print (a,b) test(1 ,b = 4 )
1 4
三.可变与不可变参数 实质上是传入变量中的数据,但指向一个对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def test (a ): a = 20 x = 10 test(x)print (x) def test (a ): a[0 ] = 20 y = [1 ,2 ,3 ] test(y)print (y)
10
[20, 2, 3]
1 2 3 4 5 6 def test (a ): a[0 ] = 20 z = (1 ,2 ,3 ) test(z)print (z)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[92], line 5
3 a[0] = 20
4 z = (1,2,3)
----> 5 test(z)
6 print(z)
Cell In[92], line 3, in test(a)
2 def test(a):
----> 3 a[0] = 20
TypeError: 'tuple' object does not support item assignment
四.匿名函数 没有名字,可以有任意数量的参数,但只能包含一个表达式,并返回该表达式的结果。用lambda定义匿名函数。
lambda arguments: expression
1 2 3 4 5 6 7 8 9 10 fn = lambda x:x+1 print (fn(1 )) is_even = lambda x: "Even" if x % 2 == 0 else "Odd" print (is_even(4 )) print (is_even(7 ))
2
Even
Odd
五.内置函数 1 2 3 4 5 6 7 8 9 10 11 print (all ([True , True , False ])) print (all ([1 , 2 , 3 ])) print () print (any ([False , False , False ])) print (any ([1 , 2 , 3 ]))
False
True
False
True
1 2 3 4 print (sum ([1 ,2 ,3 ,4 ,5 ]))
15
1 2 3 4 5 6 7 8 9 10 11 l = (1 , 5 , 3 , 2 , 4 )print (sorted (l)) l = (1 , 5 , 3 , 2 , 4 )def my_key (x ): return x % 3 print (sorted (l, key=my_key))
[1, 2, 3, 4, 5]
[3, 1, 4, 5, 2]
这里补充一个小知识:经典的math库中abs()表示取绝对值
1 2 3 4 5 6 7 8 9 10 x = reversed ([1 , 2 , 3 ]) re = list (x) print (x,type (x))print (re)
<list_reverseiterator object at 0x0000019B8496A530> <class 'list_reverseiterator'>
[3, 2, 1]
1 2 3 4 5 6 7 8 9 def fn (x ): return print (callable (fn))print (callable (print ))print (callable (123 ))
True
True
False
1 2 3 4 5 6 7 8 9 10 a = [1 , 2 , 3 ] b = ('name' ,'age' ) c = ('clocky' ,'20' ) x = zip (a,b,c)print (x,type (x))print (list (x))
<zip object at 0x0000019B84F18880> <class 'zip'>
[(1, 'name', 'clocky'), (2, 'age', '20')]
1 2 3 4 5 6 7 8 code = '''for i in range(3): print(i)''' exec (code)
0
1
2
1 2 3 4 5 6 for key in globals (): print (key)
__name__
__doc__
__package__
__loader__
__spec__
__builtin__
__builtins__
........
1 2 3 4 5 6 7 8 def fn (x ): y = x + 1 print (locals ()) fn(1 )
{'x': 1, 'y': 2}
1 2 3 4 5 6 7 8 numbers = [1 , 2 , 3 , 4 , 5 ] filtered = filter (lambda x: x**2 , numbers)print (filtered,type (filtered))print (list (filtered))
<filter object at 0x000002A4449C1F60> <class 'filter'>
[1, 2, 3, 4, 5]
5.1 高阶函数 5.1.1 map 1 2 3 4 5 6 7 8 9 10 x = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ]def is_even (n ): if n % 2 == 0 : return n even_numbers = map (is_even, x)print (list (even_numbers))
[None, 2, None, 4, None, 6, None, 8, None, 10]
5.1.2 reduce 1 2 3 4 5 6 7 8 9 10 11 12 13 14 from functools import reduce x = [1 , 2 , 3 , 4 , 5 ]def fn (a,b ): print (a,b) return a+b re = reduce(fn,x,0 ) print ()print (re)
0 1
1 2
3 3
6 4
10 5
15
六.变量作用域
指在程序中某个变量的有效范围,也就是在代码的哪个部分可以访问或修改该变量
Python中的变量作用域遵循LEGB规则(Local, Enclosing, Global, Built-in),依次搜索变量的定义位置
函数内部可以访问内部变量和外部的全局变量,外部则不能访问内部局部变量
6.1 Local→局部作用域 在函数调用时被创建,在函数调用后自动销毁。
6.2 Enclosing→嵌套作用域
指外层函数中的变量,在内层函数中可访问,但不可修改。
当一个函数嵌套在另一个函数内部时,外层函数的变量属于Enclosing作用域
内层函数变量若与外层变量同名,则优先选择内层
实质上就是在最内层找到变量,若找不到,则继续往外层找,一层一层直到找到为止。
1 2 3 4 5 6 7 8 9 10 11 def fn1 (): a = 100 def fn2 (): a = 200 print (a) fn2() fn1()
200
6.3 全局作用域
6.4 Built-in→内建作用域
6.5 函数调用问题 1 2 3 4 5 a = [1 ,2 ,3 ,lambda x:x+1 ] a[3 ](1 )
2
1 2 3 4 5 6 7 8 9 10 11 12 13 a = 1 def fn (): print (a) def fn1 (): a = 2 fn() fn1()
1
修改变量的值
1 2 3 4 5 6 7 8 9 x = 1 def f1 (): print (x) x = 2 f1()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
Cell In[31], line 7
4 print(x)
5 x = 2
----> 7 f1()
Cell In[31], line 4, in f1()
3 def f1():
----> 4 print(x)
5 x = 2
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
1 2 3 4 5 6 7 8 9 10 11 12 a = 1 def f1 (): global a print (a) a = 2 f1()print (a)
1
2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 a = 1 def foo (): a = 2 def foo1 (): nonlocal a print (a) a = 3 foo1() print (a) foo()print (a)
2
3
1
1 2 3 4 5 6 7 8 def f1 (): def f2 (): print (__name__) f2() f1()
__main__
6.6 函数内层分配 1.将函数代码存储到代码区,函数中代码不执行。
2.调用函数时,在内存中开辟空间(栈帧),存储函数内部定义的变量。
3.函数调用后,栈帧立即被释放。
七.递归函数 1 2 3 4 5 6 7 8 9 10 11 12 13 a = 1 def fn (): pass def fn1 (): print (a) print (fn()) print (fn1()) fn1()
1 None
1 None
1 None
...
1 None
1 None
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
Cell In[40], line 10
8 print(fn())
9 print(fn1())
---> 10 fn1()
Cell In[40], line 9, in fn1()
7 print(a)
8 print(fn())
----> 9 print(fn1())
Cell In[40], line 9, in fn1()
7 print(a)
8 print(fn())
----> 9 print(fn1())
[... skipping similar frames: fn1 at line 9 (2972 times)]
Cell In[40], line 9, in fn1()
7 print(a)
8 print(fn())
----> 9 print(fn1())
Cell In[40], line 7, in fn1()
6 def fn1():
----> 7 print(a)
8 print(fn())
9 print(fn1())
File c:\Users\Clocky7\anaconda3\envs\start1\Lib\site-packages\ipykernel\iostream.py:664, in OutStream.write(self, string)
655 def write(self, string: str) -> Optional[int]: # type:ignore[override]
656 """Write to current stream after encoding if necessary
657
658 Returns
(...) 662
663 """
--> 664 parent = self.parent_header
666 if not isinstance(string, str):
667 msg = f"write() argument must be str, not {type(string)}" # type:ignore[unreachable]
RecursionError: maximum recursion depth exceeded
1 2 3 4 5 6 7 8 9 a = 1 def fn (x ): if x >= 5 : return 5 else : return fn(x+1 ) fn(a)
5
1 2 3 4 5 6 7 8 9 10 11 def jiecheng (a ): if a <= 1 : return 1 else : return a * jiecheng(a - 1 ) print (jiecheng(5 ))
120