函数返回值:许多静态类型的语言主张一个函数的类型就是其返回值的类型。在 python 中, 由于python 是动态地确定类型而且函数能返回不同类型的值,所以没有进行直接的类型关联。因为重载并不是语言特性,程序员需要使用 type()这个内建函数作为代理,来处理有着不同参数类型的函数的多重声明以模拟类 C 语言的函数重载(以参数不同选择函数的多个原型)。
函数和过程:函数有返回值,过程没有返回值。Python中过程形式上就是没有返回值的函数,Python隐含的返回了一个none对象。
定义函数:
def<func_name>([arg1][,arg2, … ,argn]):
调用函数:前向引用
<func_name>([para1][,para2, … ,paran ])
#para1 – paran 与 arg1 – argn 一一对应。
和其他高级语言类似函数在被调用前必须先要被定义。Python 不允许在函数未声明之前,对其进行引用或者调用.
<func_name>([arg1=para1][,arg2=para2,… ,argn=paran])
#使用关键字指定参数,参数顺序可以打乱。
默认参数:定义函数时可给部分参数指定默认值。
<func_name>(arg1,arg2=para2)
调用时可以不同给出arg2,让程序以para2参数值进行计算。
Python中函数是一个对象,因此可以用句点操作符访问他的属性。比如:__doc__, name, version 等等。
传递函数: 回调函数
Python的函数是对象,可以作为值赋给其他变量。赋值时只需要指定函数名即可,形式上类似与给函数指定一个新的函数名:
def a(i):
printi
b=a
b(3)
>>>3
类似的可以把函数当作参数传递给另一个函数:
def a(i):
printi
def b(c):
c(3)
b(a)
>>3
装饰器:是函数调用之上的修饰,而所谓修饰就是一些额外的操作调用。这些操作调用只在声明函数的时候起作用。和创建一个组和函数是等价的:
@deco2
@deco1
def func(arg1, arg2, ...): pass
这和创建一个组合函数是等价的。
def func(arg1, arg2, ...): pass
func = deco2(deco1(func))
带参数的装饰器:
@deco1(deco_arg)
@deco2
def func(): pass
这等价于:
func =deco1(deco_arg)(deco2(func))
装饰器也可以称为装饰器函数,在形式上包含了一个内嵌函数并把该内嵌函数当作返回值返回的函数。在装饰器函数的内嵌函数中调用了被装饰函数。装饰器函数目的是提供“装饰”操作,可以有参数也可以不带参数。在定义其他函数前指定用哪些函数作为装饰(@装饰函数名)。
def bf(f):
deffb():
print'Before call the function: '
f()
returnfb
@bf
def f():
print'Run the function: '
f()
不定长参数: *元组(非关键字参数) 和 **字典(关键字参数)
可变长的参数元组(非关键字)必须在位置和默认参数之后,带元组(或者非关键字可变长参数)的函数普遍的语法如下:
def function_name([formal_args,]*vargs_tuple):
例:def tupPara( arg1, arg2=’Y’,*theRest):
tupPara(1,’N’,1,2,3,4,5)
arg1=1, arg2=’N’,theRest=(1,2,3,4,5)
不定数目的关键字的情况中, 参数被放入一个字典中,字典中键为参数名,值为相应的参数值。关键字变量参数应该为函数定义的最后一个参数,带**。
deffunction_name([formal_args,][*vargst,] **vargsd):
例:defdicPara(arg1, arg2,**theRest):
dicPara(1,’N’,a=1,b=2,c=3)
arg1=1, arg2=’N’ theRest={a:1,b:2, c:3}
内嵌函数:
将函数的定义放到一个函数的内部, 即内嵌函数的函数体位于外部函数的作用域内。因此只有在外部函数内部能调用内嵌函数。
lambda表达式:lambda [arg1[, arg2, ... argN]]: expression
Python中lambda表达式隐含的返回一个函数。lambda表达式创建了一个匿名函数。
函数式编程: 即所有的语句都是函数调用,而且函数可以作为另一个函数的参数。Python有些内置函数是函数式编程模式的,如:
reduce(func, seq[, init]): 将二元函数作用于 seq 序列的元素,每次携带一对(先前的结果以及下一个序列元素),连续的将现有的结果和下雨给值作用在获
得的随后的结果上,最后减少我们的序列为一个单一的返回值;如果初始值 init 给定,第一个比较会是 init 和第一个序列元素而不是序列的头两个元素。
偏函数:currying概念将函数式编程,默认参数,可变参数的概念结合在一起。curried的函数固化第一个参数为固定参数,并返回另一个带n-1个参数的函数对象。functional模块中的partial()函数可以实现该功能。
例:add(1,arg2) 两个参数可转换为带一个参数的新函数,第一个参数被当作固化参数(默认参数)。add1=partial(add, 1) 这句话的意思是将函数add和他的第一个参数(值为1)一起重新打包为一个新函数add1.
变量作用域和命名空间:全局变量会被局部变量覆盖,为了明确地引用一个已命名的全局变量,必须使用 global 语句。global 的语法如下:
global var1[, var2[, ... varN]]]。
lambda表达式中变量的作用域也是要注意的。
递归:
与c语言同
生成器:---对于这个概念还是理解的模糊
什么是python 式的生成器?从句法上讲,生成器是一个带 yield 语句的函数。一个函数或者子程序只返回一次,但一个生成器能暂停执行并返回一个中间的结果----那就是 yield 语句的功能, 返回一个值给调用者并暂停执行。当生成器的 next()方法被调用的时候,它会准确地从离开地方继续下一个yield语句。所以生成器的next()函数就是执行下一个yield语句。效果就是可以对函数中的操作步骤进行迭代控制。
一个生成器例子:
定义:
from randomimport randint
defrandGen(aList):
while len(aList) > 0:
yield aList.pop(randint(0, len(aList)))
调用:
>>>for item in randGen(['rock', 'paper', 'scissors']):
... print item
...
scissors
rock
paper
闭包:---对于这个概念还是理解的模糊
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是 closure。定义在外部函数内的但由内部函数引用或者使用的变量被称为自由变量。闭包将内部函数自己的代码和作用域以及外部函数的作用结合起来。闭包的词法变量不属于全局名字空间域或者局部的--而属于其他的名字空间,带着“流浪"的作用域。
def counter(start_at=0):
count= [start_at]
defincr():
count[0]+= 1
returncount[0]
returnincr
cnt=counter(2)
print cnt() 结果是2
print cnt() 结果是3
print cnt() 结果是4
这里的效果是将count变量作用域改变了。两次cnt()函数的调用之间保留了count变量的作用域,从而实现了叠加求和而不是每次都从初始值计算。