函数;
目的:重复使用
函数名是函数的引用
函数中的局部变量和全局变量同名,用global声明
参数可以是数据类型和函数
参数可以是值和函数
返回值可以是值和函数,默认返回None
函数名:
函数名也是变量,函数名就是一个引用
函数调用:
函数名是一个引用,指向函数对象,因此可以把函数名赋给一个变量,让变量指向函数对象,相当于给这个函数起个别名
返回值:
return语句:
目的:结束函数,返回值
python函数和方法默认都有返回值,默认返回值是return None
return None可以简写为return
return语句返回多个值:返回多个值就是返回一个tuple,返回tuple时,函数可以省略括号,而多个变量接收一个tuple,按位置赋给对应的值
函数作为返回值
展示形式是,在函数内部,在定义一个函数,执行外部函数的时候,返回内部函数
返回函数就是执行函数,并返回值
参数列表:
函数需要传入3个参数,当传入list时相当于一个参数
在 python 中,strings, tuples, 和 numbers 是不可变对象,而 list,dict 等则是传可变对象。
传不可变对象,传入参数时按值传递,不会改变自身
传可变对象,传入参数时按引用传递,会改变自身
函数和方法的参数能用父类的用父类,这是原则
默认参数必须指向不对对象:
原因-默认参数的值在函数定义时就已经计算出来的
函数的参数可以是变量,或者函数
因为变量指向函数,所以对一个函数可以直接传入函数当作参数,这种函数叫做高阶函数
默认参数
作用:默认参数可以简化函数的调用,可以少传几个参数
设置默认参数注意点:
1是必选参数在前,默认参数在后,否则python解释器会报错
2是如何设置默认参数
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以当作默认参数
有多个默认参数时,调用函数时候,既可以按顺序提供默认参数,没有提供的参数使用默认值
当不按顺序提供部分默认参数时,需要把参数名写上。比如调用enroll('Adam', 'M', city='Tianjin')
在函数定义时,默认参数的值就被计算出来了,且只计算一次
可变参数
顾名思义,可变参数就是传入的参数个数是可变的
只需要在参数前面加个星号*就可以了
已经有一个list或者tuple了,怎么调用一个可变参数
Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去
可变参数允许你传入0个到任意个元素
list和tuple算一个值
可变参数和定义list参数有什么区别:
list参数相当于一个参数,传入参数也是一个list
调用函数时传入可变参数,*list,把一个tuple拆分成多个元素,传入多个参数,可传入位置参数,默认参数,可变参数中
调用函数时传入多个参数,**dict,把一个dict拆分成多个元素,传入多个参数,可传入命名关键字参数,关键字参数
函数内部接收:
传入多个可变参数,函数内部自动会把这些参数组成一个tuple
传入多个关键字参数,函数内部自动会把这些参数组成一个dict
要注意定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})。
使用*args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
关键字参数
关键字参数有什么用?它可以扩展函数的功能,把用户相传的参数传上来
为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
参数:
参数超过5个时需要打包传,把参数都传入list中
局部变量的作用域是在函数内,局部变量在执行函数时创建,函数执行完成后删除,也就是说在函数外部局部变量不存在
局部变量名字和全局变量的名字相同,同名的局部变量就是新的变量
函数内改变全局变量用global关键字
局部变量和全局变量用不同的名字
global globvar # 使用 global 声明全局变量
globvar = 1
2、一个global语句可以同时定义多个变量,如 global x, y, z。
函数的结束:
函数执行到最后一条语句或是遇到return时结束
高级函数:
变量可以指向一个函数=====>函数名就是一个变量
因为变量指向函数,所以对一个函数可以直接传入函数当作参数,这种函数叫做高阶函数
高阶函数就是让函数的参数接收别的函数
map(),reduce(),filter(),sorted()
对于函数我们只关心参数和返回值,以及函数的作用
返回值:可以是函数、变量、多个变量
闭包:
闭包的概念:内部函数保存外部函数的参数和局部变量指向的引用
我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
当一个函数返回值是他的内部函数时,相关参数和变量都保存在返回函数中
相关参数保存的是值,变量保存的是引用,变量一般保存的都是引用,
所以返回闭包时牢记的一点就是:返回函数中变量不要引用任何循环变量,或者后续会发生变化的变量。
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
>>> def count():
... fs = []
... for i in range(1, 4):
... def f(j):
... def g():
... return j*j
... return g
... fs.append(f(i))
... return fs
...
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9
匿名函数:
目的:
懒得定义一个函数,或者为了和别的函数名不冲突
一般使用一次
使用方式:
lambda x:x*x lambda关键字定义匿名函数,冒号前面是参数,冒号后面是表达式
限制:只有一个表达式,不用写return,返回值就是该表达式的值
作用:用匿名函数的有个好处,因为函数没有名字,不必担心函数名冲突。此外匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
匿名函数也可以用来当返回值
装饰器:
目的:不改变函数内部的代码,在函数运行期间动态的增加功能的方法
装饰器:decorator就是一个函数,他可以接收一个函数,并返回一个函数,新功能都在返回的函数中,返回的函数中又调用了传入的函数
在函数运行期间动态的增加功能的方式
使用方式:
由于在python中函数也是一个对象,所以函数可以赋值给变量,所以通过变量也能调用该函数
对于任意函数,都可以用func(*args,**kw)的形式调用它,无论函数的参数如何定义
函数名字赋值给变量,以及把函数名()赋值给变量的区别
把一个函数赋值给变量,把一个函数的返回值赋值给变量
B return一个函数,那么这个函数什么时候,那么在B()运行时就会执行这个函数
在函数中定义一个新函数,并把新函数当作返回值返回
装饰器本质是一个函数,调用时通过注解来调用
@log
def now():
print '1' 等于 now=log(now)
三层嵌套的decorator相比now=log('exute')(now)
表现形式:在函数的方法上面@log,表示装饰器,
现在,只需记住在定义wrapper()的前面加上@functools.wraps(func)即可,装饰器函数中的功能函数需要跟上这句话,保持函数签名为传入函数的签名
decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。
@log
def now():
print '2013-12-25'
def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
偏函数:
目的:
设置函数参数为默认值
怎么用偏函数:
传入函数对象和默认参数,生成一个新函数
functools.partial(int,base=2)的作用:就是把一个函数的某些参数设置固定值,返回一个新函数,调用该函数会更简单
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
python访问修饰符:
正常的函数和变量都是公开的
__XX__形式的变量是特殊变量,有特殊作用的变量,如__name__,__author__
类似_xx,__xx形式的函数和变量是非公开的private,不应该被直接应用,如_abc,__abc
定义public还是private是根据函数和变量要不要被外部调用的,如果需要外部调用的就用public,如果不需要外部调用的就是private
空函数:
没有函数体的函数叫空函数
def nop():
pass
pass用来当做占位符,让代码能运行起来,缺少了pass,代码运行时会有语法错误
12、对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的
*args会把一个tuple拆分成多个元素,传入多个参数,可传入位置参数,默认参数,可变参数中
**kw会把一个dict拆分成多个元素,传入多个参数,可传入命名关键字参数,关键字参数