函数设计注意点:
耦合性:尽量不要使用全局变量;尽量不要改变函数中接收的可变实参的值;避免直接更改另一个模块文件中的变量。
聚合性:每个函数都有一个单一的,统一的目标,并且函数尽可能的小。
Python的函数是一个对象,函数对象可以赋值给其他名字,传递给其他函数,嵌入到数据结构。而对于用于def语句中的名称,它只是当前作用域的一个变量赋值,def运行之后,该名字指向了函数对象,我们可以把该对象赋给其他对象,同时我们也可以给这个函数名赋予其他对象。
>>> def echo(message): #给变量echo赋予一个函数对象
... print(message)
...
>>> echo
<function echo at 0xb70760ac>
>>> x=echo #把函数对象赋予其他变量
>>> x('hello world')
hello world
>>> echo=5 #给变量echo赋予一个整数对象
>>> echo
5
函数内省
因为函数也是对象,所以我们也可以像一个类一样,通过.引用来查看它的属性的值;而通过在引用dir方法,可以深入探索下一层的细节。
>>> def fun(a):
... print(a)
...
>>> dir(fun)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',... , '__subclasshook__']
>>> fun.__code__
<code object fun at 0xb71532a0, file "<stdin>", line 1>
>>> dir(fun.__code__)
['__class__', ..., 'co_argcount', ..., 'co_varnames'] #注意比较长的是两个_,因为是文件名的连接,所以中间是一个短线
>>> fun.__code__.co_varnames
('a',)
>>> fun.__code__.co_argcount
1
函数属性
除了上面我们查看到的函数属性,我们也可以通过手动添加一个新的属性。
>>> fun.count=0 #手动添加属性count,
>>> dir(fun) #通过dir方式,你可以查看count已经添加到fun的属性中
['__annotations__', ...,'__sizeof__', '__str__', '__subclasshook__', 'count']
函数注解
注解信息:与函数的参数和结果相关的任意的用户定义的数据。它是可选的,出现的时候直接附加到函数对象的__annotations__,注解它编写在def头部行,所以我们只有在定义函数的时候才能对它进行设置。我们只对变量和函数返回值进行注释。
参数的注释 :在参数后面加个冒号和注释信息。如果你想对参数设置默认值的话,它处在注释之后。
返回值的注释 :在参数列表之后冒号之前加一个->后面是标注信息
>>> def fun(a:'spam'=4, b:(1,10)=5, c:float=6) -> int:
... return a+b+c
...
>>> fun.__annotations__
{'a': 'spam', 'c': <class 'float'>, 'b': (1, 10), 'return': <class 'int'>}
lambda
lambda表达式:一个或多个参数,紧接着一个冒号,之后是表达式。lambda argument1,argument2,...argument3:expression using arguments
lambda引入的本地作用域更像一个嵌套的def语句,将会自动从上层函数中,模块中以及内置作用域中(通过LEGB法则)查变量
>>> def knights():
... title ='sir'
... action =(lambda x='fee':title+x) #默认值方式,它把表达式作为返回值
... return action
...
>>> act=knights()
>>> act('hello')
'sirhello'
在序列中映射函数:map
map 函数会对一个序列对象中的每一个元数应用被传入的函数,并且返回一个包含了所有调用结果的列表。因为它第一个参数期待函数对象,所以常与lambda配合
>>> map((lambda x:x+3),(1,2,3)) #仅仅得到的是函数对象
<map object at 0xb707544c>
>>> list(map((lambda x:x+3),(1,2,3)))
[4, 5, 6]
>>> list(map(pow,[1,2,3],[2,3,4])) #赋予一个N参数的函数用于N序列,并行处理序列,并返回结果
[1, 8, 81]
filter 和 reduce
filter 基于某一个测试函数过滤一些元数
reduce 对每对元素都应用函数并运行到最后结果
>>> list(filter((lambda x: x>0),range(-5,5))) #序列中大于0的选出来
[1, 2, 3, 4]
>>> from functools import reduce
>>> reduce((lambda x, y:x+y),[1,2,3,4])
10