标签:python 装饰器
1、反射之__import__
我们知道import语句是用来导入外部模块的,当然还有from...import...也可以,但是其实import实际上是使用builtin函数__import__来工作的。
在一些程序中,我们可以动态地去调用函数,如果我们知道模块的名称(字符串)的时候,我们可以很方便的使用动态调用。
__import__(module_name[, globals[, locals[, fromlist]]]) #可选参数默认为globals(),locals(),[]
__import__(‘os‘)
__import__(‘os‘,globals(),locals(),[‘path‘,‘pip‘]) #等价于from os import path, pip
例: 以字符串的形式导入模块
mod = __import__(‘sys‘)
print(mod.path)
例:以字符串的形式调用模块中的函数
func = getattr(mod,‘path‘)
print(func)
例:从一个包中导入一个模块 ,包名为main,模块名为mod
aa = __import__(‘main.mod‘)
aa = __import__(‘main‘, globals={}, locals={}, fromlist=[‘mod‘])
aa = __import__(‘main‘,globals(),locals(),[‘mod‘])
m = getattr(aa, ‘mod‘)
print(m.first(‘kevin‘))
n = getattr(m, ‘first‘)
print(type(n))
n(‘kevin‘)
注:web框架中根据不同的URL,来加载不同的模块,进行不同的处理。
2、装饰器
装饰器的语法以@开头,接着是装饰器要装饰的函数的申明等。
其实总体说起来,装饰器其实也就是一个函数,一个用来包装函数的函数,装饰器在函数申明完成的时候被调用,调用之后申明的函数被换成一个被装饰器装饰过后的函数。
当原函数有形参时,在装饰的函数中也需要有相应的形参func(args);
当原函数有return返回值时,在装饰的函数中也必须有returne func(args);
装饰器分为无参装饰和有参装饰:
★无参装饰
定义方法如下:
比如先定义一个装饰方法:
def deco(func):
"""无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法"""
print(‘第一个装饰器‘) #进行额外操作
return func #返回一个可调用对象(此例还是返回作为输入参数的方法),返回一个新函数时,新函数可以是一个全局方法或者decorator函数的内嵌函数,只要函数的签名和被装饰的函数相同
@deco
def MyFunc(args): #应用@deco修饰的方法
print(‘my first decorator‘,args)
return(‘nihao‘,args)
MyFunc(‘wangkai‘) #调用被装饰的函数
MyFunc(‘kevin‘)
info = MyFunc(‘gonghui‘)
print(info)
注意:当使用上述方法定义一个decorator方法时,函数体内的额外操作只在被装饰的函数首次调用时执行;
如果要保证额外操作在每次调用被装饰的函数时都执行,需要换成如下的写法:
def deco(func):
def replaceFunc(args): #定义一个内嵌函数,此函数包装了被装饰的函数,并提供额外操作的代码
print(‘第一个装饰器‘) #进行额外操作
return func(args) #产生对被装饰函数的调用
return replaceFunc #由于返回的是这个新的内嵌函数,所以确保额外操作每次调用得以运行
@deco
def MyFunc(args): #应用@deco修饰的方法
print(‘my first decorator‘,args)
return(‘nihao‘,args)
MyFunc(‘wangkai‘) #调用被装饰的函数
MyFunc(‘kevin‘)
info = MyFunc(‘gonghui‘)
print(info)
★有参装饰:
def decoWithArgs(arg):
"""由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数,
所以必须返回一个decorator函数, 由它对被装饰的函数进行封装处理"""
def newDeco(func): #定义一个新的decorator函数
def replaceFunc(args): #在decorator函数里面再定义一个内嵌函数,由它封装具体的操作
print(‘第一个装饰器‘) #进行额外操作
aa = func(args) #对被装饰函数进行调用
print(‘再见‘)
return aa
return replaceFunc
return newDeco #返回一个新的decorator函数
@decoWithArgs("demo")
def MyFunc(args): #应用@decoWithArgs修饰的方法
print(‘my first decorator‘,args)
return(‘nihao‘,args)
MyFunc(‘wangkai‘) #调用被装饰的函数
MyFunc(‘kevin‘)
info = MyFunc(‘gonghui‘)
print(info)
当我们对某个方法应用了装饰方法后, 其实就改变了被装饰函数名称所引用的函数代码块入口点,使其重新指向了由装饰方法所返回的函数入口点。由此我们可以用decorator改变某个原有函数的功能,添加各种操作,或者完全改变原有实现。
本文出自 “秋天的童话” 博客,请务必保留此出处http://wushank.blog.51cto.com/3489095/1656952
标签:python 装饰器
原文地址:http://wushank.blog.51cto.com/3489095/1656952