- Python中能被调用(called)的东西就是callable。就是加小括号可以运行的东西。
- 函数是什么?
- python中所有东西都是object, 函数也是,是一个普通的object,在字节码中函数体被解析成了一个code object 保存的是运行逻辑,然后把code object load进来,然后把名字load进来,然后做了一个function object, 就是把这个code object变成了一个有名字的function object, 然后保存到这个函数的名字里面。
- 所以定义一个函数的时候,就是新建了一个变量,然后变量保存了一个函数对象function object。
- 函数对象是一个callable。
- 函数就是一个普通的对象,所以函数就可以当作参数,也可以作为返回值。
- 装饰器就是参数是函数,返回值也是函数的一个函数。
- 语法就是@语法糖,加一个函数,被装饰的函数作为参数传入decorator,返回值也是我的这个函数。
- 作用就是在不改变我被装饰的函数的功能情况下,扩展一些其他的功能。
- 同时一个装饰器也可以装饰多个函数。
- from functools import wraps, 来保__name__和__doc__也是被装饰函数的.魔术方法
def outer(func):
@wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
return res
return wrapper
import time
def timeit(n):
def inner(func):
def wrapper(*args, **kwargs):
start = time.time()
for i in range(n):
res = func(*args, **kwargs)
print(time.time() - start)
return res
return wrapper
return inner
@timeit(1000)
def double(x):
return x*2
double = timeit(1000)(double)
python中用到的装饰器
- @property
- 是一个函数,但是可以作为属性去访问
- 与所定义的属性配合使用,可以作为只读属性。这样可以防止属性被修改。
class DataSet(object):
def __init__(self):
self._images = 1
@property
def images(self):
return self._images
- @staticmethod
- 直接类名.方法名()来调用
- 这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
- @classmethod
- 直接类名.方法名()来调用
- 这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
扩展
- 类加括号调用了__init__方法来创建一个实例对象。这一过程分成了两步: 类调用__new__来创建实例对象,__new__调用__init__来初始化实例对象。
- 实例对象加上括号会调用__call__方法,一般作为程序的入口