python中的@函数修饰符
解释:(1)修饰符是一个函数(2)修饰符取被修饰函数(或其他的变量,比如类class)为参数(3)当修饰符内部存在返回函数时,修饰符将返回该函数作为结果(4)修饰符维护被维护函数的签名。一般使用时,我们会比较注重前三种需求。注:只有修饰符函数有return时,才调用被修饰函数;否则,不能够调用被修饰函数。
参考:https://www.cnblogs.com/wolf-yasen/p/11240500.html https://blog.csdn.net/txwsmsm7023_/article/details/104900636
https://zhuanlan.zhihu.com/p/265779360
https://fishc.com.cn/thread-51109-1-1.html
https://www.cnblogs.com/gdjlc/p/11182441.html
https://blog.csdn.net/972301/article/details/59537712
https://blog.csdn.net/whatday/article/details/84761344
https://www.cnblogs.com/wanghui-garcia/p/11431662.html
https://blog.csdn.net/u013205877/article/details/78872278
python中的@类修饰符
解释:对于带参数的修饰符,参数首先传入修饰符函数中,然后返回一个函数A,接着被修饰类作为函数A的参数进行下一步处理;对于不带参数的修饰符,类直接作为修饰符函数的参数。对于参数完整的修饰符,类修饰符不需要显式的调用,即可执行;而当出现类对象实例化时,执行初始化函数。
参考:
https://cloud.tencent.com/developer/article/1566268 https://blog.csdn.net/gavin_john/article/details/50923988 https://www.cnblogs.com/zhzhang/p/11375774.html
https://www.cnblogs.com/f-ck-need-u/p/10205168.html
https://blog.csdn.net/m0_47671192/article/details/106091380
下图中,build_dict(“dot”)函数和直接调用dopatt()来进行对象初始化一样,都是定义了一个对象,因此触发了类的初始化函数。核心的问题在于reg_att_cls()中的return cls。具体理解流程:@reg_att(dot)->reg_att_cls->reg_att_cls(dopatt)->return cls(类):(1)当build_dict(“dot”)时,实际上是通过return Test_dict[name]=cls声明一个类对象,因此会启用初始化函数;(2)c=dopatt(),其实是指经过了修饰符的运算后,又返回到了类定义(return cls),和直接的定义类对象没有区别,因此调用了初始化函数。
下图中,build_dict(“dot”)函数和上图的解释相同。但是由于直接类声明对象时,修饰符函数已经不返回任何信息,因此无输出。
# Test the @
import torch.nn as nn
Test_dict={}
def build_dict(a_type,*arg,**kwargs):
return Test_dict[a_type](*arg, **kwargs)
def reg_att(name):
def reg_att_cls(cls):
print("This is in reg_att_cls")
if name in Test_dict:
print("Cannot reg attention")
Test_dict[name] = cls
return cls
print("This is in reg_att, and will enter into reg_att_cls")
return reg_att_cls
class Batt(nn.Module):
def __init__(self):
super().__init__()
@reg_att("dot")
class dopatt(Batt):
def __init__(self):
print("this is the class")