在python,一切都是对象,函数也和其他对象一样,可以赋值给其他的名字、传递给其他函数、嵌入到数据结构。
而函数名直接是一个对象的引用。
def echo(message):
print(message)
echo('direct call')
x = echo
x('Indirect call')
def indirect(func, arg):
func(arg)
indirect(echo, 'argument call')
schedule = [(echo,'spam'),(echo, 'ham')]
for (func, arg) in schedule:
func(arg)
函数对象也有着属性
>> func.__name__
'func'
>> dir(func)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>dir(func.__code__)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_posonlyargcount', 'co_stacksize', 'co_varnames', 'replace']
函数不仅仅只有python原来自带的属性,还可以通过自己附加属性,
func.count = 0
func.count += 1
函数注解通常编写在def头部
def func(a:'spam', b:(1,10), c:float) -> int:
return a+b+c
>> func(1,2,3)
6
调用一个注解过的函数和以前一样。但是当注解出现时,python将之收集到字典种,参数名变成键,注解变成值
>>> func.__annotations__
{
'a': 'spam', 'b': (1, 10), 'c': <class 'float'>, 'return': <class 'int'>}
编写了注解后仍然能够使用默认值
def func(a:'spam'=4,b:(1,10)=5,c: float = 6) -> int:
return a+b+c
lambda不能使用注解
lambda又称匿名函数,因为它不需要像def那样要函数变量名
lambda表达式
lambda arg1,arg2,argN: expression using args
lambda起到了函数速写的作用,允许在执行的代码嵌入函数定义。
L = [lambda x : x**2,
lambda x : x**3,
lambda x : x**4]
for f in L:
print(f(2))
print(L[0](3))
当需要把小段的可执行代码编进def不能编进的代码中,lambda就起到了很好的作用
def f1(x): return x**2
def f2(x): return x**3
def f3(x): return x**4
L = [f1,f2,f3]
for f in L:
print(f(2))
print(L[0](3))
并且通过写lambda函数可以避免函数名与其他变量名重复。
lambda 是嵌套函数作用域查找的最大受益者,通常lambda出现def中(很典型的情况)lambda可以能够获取上层函数的变量作用域。
def action(x):
return (lambda y:x+y)
>>> act = action(99)
>>> act(2)
101
程序通常有要求对列表中的每一个元素进行一个操作并将其结果集合起来。
例如,对每一个列表进行加10
counters = [1,2,3,4]
updated=[]
for x in counters:
updated.append(x+10)
python提供了内置的工具map来完成此操作
def inc(x): return x+10
list(map(inc, counters))
map期待传入一个函数和一个列表,那么用lambda就可以避免独立成立一个函数
list(map(lambda x:x+10,counters))
当函数需要多个参数时,也可以提供多个列表来完成操作
pow(3,4)
>> 81
list(map(pow,[1,2,3],[2,3,4]))
[1,8,81]
map期待一个N参数道德函数用于N列表
filter就是过滤器的意思,基于某一测试函数过滤一些元素
list(range(-5,5))
list(filter((lambda x:x>0),range(-5,5)))
等价于
res = []
for x in range(-5,5):
if x >0:
res.append(x)
reduce接收一个迭代器来进行处理,但是返回的说单个结果
from functools import reduce
>>> reduce((lambda x,y:x+y),[1,2,3,4])
10
>>> reduce((lambda x,y:x*y),[1,2,3,4])
24
等价于
L = [1,2,3,4]
res = L[0]
for x in L[1:]:
res = res+x