1. 函数
python中的一切都是对象,包括数字、字符串、元组、列表、字典和函数。可以在此用上***args(位置参数收集)**和**kwargs(关键字参数收集)的技巧。
def answer():
print(42)
2. 内部函数
在python中,可以在函数中定义另外一个函数:
def outer(a, b):
def inner(c, d):
return c + d
return inner(a, b)
当需要在内部多次执行复杂的任务时,函数内部是 非常有用的,从而避免了循环和代码的堆叠重复。对于这样一个例子,内部函数的作用是给外部的函数增加字符串参数:
def knights(saying):
def inner(quote):
return "We are the knights who say: '%s'" % quote
return inner(saying)
3. 闭包
内部函数可以看作一个闭包。闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值。
- inner2()直接使用外部的saying参数,而不是通过另外一个参数获取
- knights2()返回值为inner2函数,而不是调用它。
def knights2(saying):
def inner2():
return "We are the knights who say: '%s'" % saying
return inner2
所以inner2()就是一个闭包:一个被动态创建的可以记录外部变量的函数。
用不同的参数调用knights2()两次:
>>> a = knights2('Duck')
>>> b = knights('Hasenpfeffer')
>>> type(a) //它们是函数也是闭包
>>> type(b) //它们是函数也是闭包
>>> a()
>>> b()
4. 匿名函数
python中,lambda函数是用一条语句表达的匿名函数。可以用它代替小的函数。
举一个使用普通函数的例子。定义函数edit_story(),参数列表如下所示:
- words —— 单词列表
- func —— 遍历列表中单词的函数
def edit_story(words, func):
for word in words:
print(func(word))
stairs = ['thud', 'meow', 'thud', 'hiss']
def enliven(word):
return word.capitalize() + '!'
edit_story(stairs, enliven)
#匿名函数
edit_story(stairs, lambda word:word.capitalize() + '!')
5. 生成器
生成器是用来创建python序列的一个对象。使用它可以迭代庞大的序列,且不需要在内存中创建和存储整个序列。通常,生成器是为迭代器产生数据的。例如:range()。
def my_range(first=0, last=10, step=1):
number = first
while number < last:
yield number
number += step
'''
yield在函数中的功能类似于return,不同的是yield每次返回结果之后函数并没有退出,而是 每次遇到yield关键字后返回相应结果,并保留函数当前的运行状态,等待下一次的调用。如果 一个函数需要多次循环执行一个动作,并且每次执行的结果都是需要的,这种场景很适合使用yield实现。包含yield的函数成为一个生成器,生成器同时也是一个迭代器,支持通过next方法获取下一个值。
'''
6. 装饰器
装饰器实质上是一个函数。它把一个函数作为输入并且返回另一个函数。在装饰器中,通常使用下面这些Python技巧
- *arg和**kargs
- 闭包
- 作为参数的函数
def document_it(func):
def new_function(*args, **kwargs):
print('Running funciton:', func.__name__)
print('Positional arguments:', args)
print('Keyword arguments:', kwargs)
result = func(*args, **kwargs)
print('Result:', result)
return result
return new_function
def add_ints(a, b):
return a + b
cooler_add_this = document_it(add_ints) # 人工对装饰器赋值
cooler_add_this(3, 5)
#Running funciton: add_ints
#Positional arguments: (3, 5)
#Keyword arguments: {}
#Result: 8
#作为对前面人工装饰器赋值的替代,可以直接在要装饰的函数前添加装饰器名字@decorator_name:
@document_it
def add_this(a, b):
return a + b
add_this(a, b)
#Running funciton: add_this
#Positional arguments: (3, 5)
#Keyword arguments: {}
#Result: 8
同样一个函数可以有多个装饰器。靠近函数定义(def上面)的装饰器最先执行,然后依次执行上面的。任何顺序都会得到相同的最终结果。例如:
def document_it(func):
def new_function(*args, **kwargs):
print('Running funciton1:', func.__name__)
print('Positional arguments:', args)
print('Keyword arguments:', kwargs)
result = func(*args, **kwargs)
print('Result:', result)
return result
return new_function
def squeare_it(func):
def new_function(*args, **kwargs):
print('Running funciton2:', func.__name__)
result = func(*args, **kwargs)
return result * result
return new_function
@document_it
@squeare_it
def add_ints(a, b):
return a + b
result = add_ints(4, 5)
print('end Result:', result)
@squeare_it
@document_it
def add_this(a, b):
return a + b
add_this(4, 5)
print('end Result:', result)
#Running funciton1: new_function
#Positional arguments: (4, 5)
#Keyword arguments: {}
#Running funciton2: add_ints
#Result: 81
#Running funciton2: new_function
#Running funciton1: add_this
#Positional arguments: (4, 5)
#Keyword arguments: {}
#Result: 9