定义函数
>>> def 函数名(): ... 函数体 ... 返回值
函数的返回值 return
>>> def testsum(): ... a=1 ... print(a) ... return a+1 # 执行完return之后不会再接着执行下面的print ... print(a) ... >>> testsum() 1 2 def info(name,age): return name,age #函数可以返回多个值 >>> x=info('jane',20) >>> print(x) ('jane', 20) # 返回一个tuple
函数的参数
参数定义的顺序是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- 必选参数
>>> def info(name): ... print(name) ... >>> info('lily') lily
默认参数
- 注意:默认参数必须要用不可变对象
-
>>> def info(name,age=22): # 默认参数需要放到参数列表的最后 ... print(name,age) ... >>> info('lily') lily 22 >>> info('lily',100) lily 100
- 可变参数 参数的个数是可变的可以是0个1个或者任意个
### *args 用来将参数打包成tuple给函数体调用
>>> def func(*arg): # arg接受的是一个tuple ... print(arg,type(arg)) ... ####方法一 >>> func(1,2,3,4) (1, 2, 3, 4) <class 'tuple'> ####方法二 >>> l=[1,2,3,4] >>> func(*l) (1, 2, 3, 4) <class 'tuple'> >>> func(l) # 不加*会把列表l当成一个元素传入元祖 ([1, 2, 3, 4],) <class 'tuple'> - 关键字参数: 允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
### **kwargs 打包关键字参数成dict给函数体调用 >>> def func(**kwarg): # kwarg接收的是一个dict ... print(kwarg,type(kwarg)) ####方法一 >>> func(k1='v1',k2='v2') {'k2': 'v2', 'k1': 'v1'} <class 'dict'> ####方法二 >>> d={'k1':'v1','k2':'v2'} >>> func(**d) {'k2': 'v2', 'k1': 'v1'} <class 'dict'> >>> func(d) ##不加**会报错 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: func() takes 0 positional arguments but 1 was given ### *args必须在**kwargs前面 >>> def func(*arg,**kwarg): ##顺序必须是*在前 **在后 ... print(arg,type(arg)) ... print(kwarg,type(kwarg)) ... >>> l = [1,2,3] >>> d = {'k2': 'v2', 'k1': 'v1'} >>> func(l,d) ## 不加* **时,会把参数当做一个元素放入元祖 ([1, 2, 3], {'k2': 'v2', 'k1': 'v1'}) <class 'tuple'> {} <class 'dict'> >>> func(*l,**d) (1, 2, 3) <class 'tuple'> {'k2': 'v2', 'k1': 'v1'} <class 'dict'>
- 命名关键字参数
#命名关键字参数需要一个特殊分隔符*, *后面的参数被视为命名关键字参数 def people(name,*,age,addr): print(name,age,addr) people('jack',age=22,addr='china') -------> jack 22 china #如果函数定义中已有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了 def people(name,*args,age,addr): print(name,args,age,addr) people('jack',age=22,addr='china') ---------> jack () 22 china #命名关键字参数必须传入参数名,否则会报错: def people(name,*,age,addr): print(name,age,addr) people('jack',22,'china') -------------> Traceback (most recent call last): File "E:/PYcharmprojects/PYscripts/DAY2/参数.py", line 12, in <module> people('jack',22,'china') TypeError: people() takes 1 positional argument but 3 were given
局部和全局作用域
- 函数外部不能访问局部变量
def your(): age = 22 your() print(age) -------------------> NameError: name 'age' is not defined
- 函数内可以访问全局变量,但是不能直接修改全局变量,除非加上global
def your(): print(age) #可以访问全局变量 age = 22 your() 结果:22 --------------------------- def your(): print(age) age = 23 #不能修改 会报错 print(age) age = 22 your() 结果:UnboundLocalError: local variable 'age' referenced before assignment ---------------------------- def your(): #print(age) age = 23 #不是全局变量 而是创建了一个跟全局变量重名的局部变量 print(age) age = 22 your() 结果:23
- 局部作用域不能访问其他局部作用域内的变量
def your(): mine() print(name) def mine(): name = 'lily' your() ---------------------> NameError: name 'name' is not defined
- 在不同的作用域,可以用相同名字来命名不同的的变量
def your(): name = 'your name' print(name) def mine(): name = 'my name' print(name) your() print(name) name = 'global' mine() print(name) -------------------->> my name your name my name global
- global 在函数里面修改函数外的变量
def spam(): global eggs # global关键字声明eggs是全局变量 eggs='spam' # 修改全局变量eggs为‘spam’ print(eggs) eggs='global' spam() def bacon(): print(eggs) bacon() -----------------> spam spam
- nonlocal 修改嵌套作用域(外层非全局作用域)中的变量
def outer(): num=1 def inner(): nonlocal num #nonlocal关键字 将嵌套作用域改为 num=10 print(num) inner() print(num) outer() -------------> 100 100
匿名函数 lambda
>>> n = lambda:25 >>> n() 25 >>> f = lambda x:x**2 # lambda表示匿名函数,x表示参数 >>> f <function <lambda> at 0x7f05b3925e18> >>> f(3) 9 def is_odd(n): return n % 2 == 1 L = list(filter(is_odd, range(1, 20))) 等同于 >>> list(filter(lambda x:x%2==1,range(1,20))) [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] >>> myabs = lambda x: -x if x < 0 else x >>> myabs(-1) 1 >>> myabs(1) 1