请指教这个python 装饰器的实现原理是什么?我懵了,函数定义没写参数,竟然可以传参我有点害怕python了。

请看下面这个装饰器和普通函数,参数传递是怎么进行的或者保存在哪里吗?
希望前辈能解释一下,我没理解。

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')
#输出:
#通过认证!
#开始执行附加功能
#开始执行函数

2个回答

这很正常。装饰器和被装饰的函数又不是一回事,为啥要参数一样。
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.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐