请看下面这个装饰器和普通函数,参数传递是怎么进行的或者保存在哪里吗?
希望前辈能解释一下,我没理解。
def new_func(func):
def wrapped(username, passwd):
if username == 'root' and passwd == '123456789':
print('通过认证!')
print('开始执行附加功能')
return func()
else:
print('用户名或密码错误')
return
return wrapped
@new_func
def orign():
print('开始执行函数')
if __name__ == '__main__':
orign('root', '123456789')
#输出:
#通过认证!
#开始执行附加功能
#开始执行函数
这很正常。装饰器和被装饰的函数又不是一回事,为啥要参数一样。
python只是在语法层面把装饰模式(设计模式的一种)封装了。这些代码,用Java一样可以实现。
Java的做法:
interface IAction
{
void orign();
}
class MyClass implements IAction
{
public void orign()
{
print("开始执行函数");
}
}
interface IAuthAction
{
void orign(String u, String p);
}
class Decorator implements IAuthAction
{
private IAction act;
public Decorator(IAction act)
{
this.act = act;
}
public void orign(String u, String p)
{
if (u.equals("root") && p.equals("123456789"))
{
print("通过认证!");
printf("开始执行附加功能");
act();
}
}
}
void main()
{
IAuthAction d = new Decorator(new MyClass());
d.orign("root", "123456789");
}
如果你对比下Java和Python的代码,你就会发现Python节约了什么
首先,在Python里,不需要Iaction和IAuthAction两个接口。这是因为Python是弱类型的。
在Java里,
Object o = new MyClass();
o.orign();
这样不可以,因为编译器不知道o的确切类型,就不能判断o是否有orign这个方法,也没办法生成调用的代码。所以必须将o声明为IAction才行。但是Python是运行时绑定的。
其次,Python内置装饰器,就不需要Decorator类了
Decorator的作用就是,将orign包装成具有两个参数的orign
在Python里,一个函数,如果能返回另一个函数(这两个函数显然参数并不要一样,好比这里的orign),那么就可以直接定义为包装器。
Python会执行包装后的函数,并且传入被包装的函数,相当于Java代码中的
IAuthAction d = new Decorator(new MyClass());
@new_func相当于orgin = new_func(orign),不信你在def函数上面去掉@行,下面补另一个,应该是装饰器原理,Python内置装饰器@。
于是就好理解了,n_f(orign)中o被当做参数传给n_f.执行。但是先不执行wrap,返回return.但是此时orign已经放入def n_f,这就是闭包现象。所以此时o
= wrap. question end.
其实return传回了内存地址。
@可以传参数,可以csdn,然后 用三个def 嵌套… 我是猜的, doge.