Python 课堂上的装饰师和学生
有没有办法在嵌套良好的类结构中编写装饰器?例如,这在没有类的情况下可以正常工作:Python 课堂上的装饰师和学生,python,decorator,Python,Decorator,有没有办法在嵌套良好的类结构中编写装饰器?例如,这在没有类的情况下可以正常工作: def wrap1(func): def loc(*args,**kwargs): print 1 return func(*args,**kwargs) return loc def wrap2(func): def loc(*args,**kwargs): print 2 return func(*args,**kwarg
def wrap1(func):
def loc(*args,**kwargs):
print 1
return func(*args,**kwargs)
return loc
def wrap2(func):
def loc(*args,**kwargs):
print 2
return func(*args,**kwargs)
return loc
def wrap3(func):
def loc(*args,**kwargs):
print 3
return func(*args,**kwargs)
return loc
def merger(func):
return wrap1(wrap2(wrap3(func)))
@merger
def merged():
print "merged"
@wrap1
@wrap2
@wrap3
def individually_wrapped():
print "individually wrapped"
merged()
individually_wrapped()
输出为:
1
2
3
merged
1
2
3
individually wrapped
这就是我想要的。但是现在让我们假设我想将合并
和分别包装为静态或类方法。只要装饰器不在类名称空间中,这也会起作用。有什么好方法可以将装饰器放在名称空间中吗?我不想列举所有不起作用的方法,但主要问题是如果merge
是一种方法,它就不能访问wrapX
方法。也许这是一件愚蠢的事情,但是有没有人在同一个类中使用了所有的decorator和decorated方法的情况下实现了这样的功能?“有什么好方法可以将decorator放在名称空间中?”
没有令人信服的理由。您有模块文件。对于一个班级和一些装饰师来说,这是一个整洁的容器
您永远不需要装饰器作为类的方法——您可以从一个方法调用另一个方法 实际上,把它们都放在一个类中应该没有问题。在类主体内部时,您可以通过命名任何迄今定义的变量来命名该变量:
class A(object):
a = 1
b = 2
c = a + b
print A.c
A类(对象):
a=1
b=2
c=a+b
印刷交流
这将产生结果3,因为当Python执行类主体时,函数可以“看到”已声明的变量a和b。因此,以下方法同样有效:
class B(object):
@staticmethod
def wrapper(*args, **kw):
...
@wrapper
def a(...):
...
B类(对象):
@静力学方法
def包装(*参数,**kw):
...
@包装纸
定义a(…):
...
现在,你的合并功能如何?问题是包装器函数在类主体完成执行后很长时间内运行,并且它定义的变量不再在封闭范围内。那你怎么能提到他们呢?使用类的名称作为前缀!像这样:
class C(object):
@staticmethod
def wrap1(*args, **kw):
...
@staticmethod
def wrap2(*args, **kw):
...
@staticmethod
def wrap3(*args, **kw):
...
@staticmethod
def merger(*args, **kw):
C.wrap1(C.wrap2(C.wrap3(...)))
@merger
def plain(...):
...
C类(对象):
@静力学方法
def wrap1(*参数,**千瓦):
...
@静力学方法
def wrap2(*参数,**kw):
...
@静力学方法
def wrap3(*参数,**kw):
...
@静力学方法
def合并(*参数,**kw):
C.wrap1(C.wrap2(C.wrap3(…))
@合并
def平原(…):
...
因此Python的一般规则是:在类主体级别上运行的代码可以讨论到目前为止在类主体中定义的所有变量和方法,这意味着您可以将这些类变量用作包装器。但是,一旦你在类中的一个函数的“内部”,不管它是一个类函数、一个静态函数还是一个方法(这个包装器是一个类方法,因为它接受args,但不接受“self”),那么你必须使用类的名称来“获取”“它的内容。很好。如果我必须通过名称来引用类,那么可能没有很好的理由将它们放在类中。是的,如果您只是想更容易地引用它们,那么可能没有理由这样做。您只需将包装器留在类之外,就可以从类定义内部和其任何函数内部“看到”包装器。可能会让事情更简单!我认为这是一条路要走。没有什么理由把他们留在课堂上。