我有一个自编的基于类的Python装饰器。当我将装饰器应用于类中的方法时,我可以看到存在差异。通常,@classmethod
,@staticmethod
,@property
或@unique
等装饰器不带括号。这些装饰器不需要参数,并且(主要是?)被编写为基于函数的装饰器。
因此,与这些示例相比,我的装饰器是基于类的,并且在应用时需要一个可选参数。
我的装饰者:
class DocumentMemberAttribute(Attribute):
def __init__(self, value=True):
super().__init__()
self.value = value
属性类(真正的装饰者):
class Attribute:
__AttributesMemberName__ = "__pyattr__"
def __call__(self, func):
self._AppendAttribute(func, self)
return func
@staticmethod
def _AppendAttribute(func, attribute):
# inherit attributes and append myself or create a new attributes list
if (Attribute.__AttributesMemberName__ in func.__dict__):
func.__dict__[Attribute.__AttributesMemberName__].append(attribute)
else:
func.__setattr__(Attribute.__AttributesMemberName__, [attribute])
def __str__(self):
return self.__name__
示例课程:
class MyClass:
def __init__(self, message=""):
super().__init__()
self.message = message
@DocumentMemberAttribute
def Method1(self):
return "foo"
@DocumentMemberAttribute()
def Method2(self):
return "bar"
@DocumentMemberAttribute(False)
def Method3(self):
return "spam"
@DocumentMemberAttribute(True)
def Method4(self):
return "egg"
附加信息用于自定义autodoc-skip-member
处理程序,以确定是否应记录或跳过方法。这类似于docit
扩展名。
因此,当我们查看生成的文档(Sphinx)时,我们可以看到这些结果:
class MyClass (message =“”)
Method1 =< lib.SphinxExtensions.DocumentMemberAttribute对象位于0x0000000004AD9E80>
方法2()
方法4()
我们在这里可以看到什么:
__str__
(或__repr__
?)来记录初始值所以我的问题:
pyAttributes是由我编写的一组属性(真实属性,没有Python属性)。它们的行为几乎与.NET中的custom-attributes一样
答案 0 :(得分:0)
正如@Ryan指出的那样,@
符号后面的字符串是一个表达式,它被转换为函数调用。该调用的参数是应用装饰器的对象。
示例1 - 基于函数的装饰器:
我将使用enum.unique
装饰器。它是作为一个函数编写的。
from enum import Enum, unique
@unique
class MyEnum(Enum):
foo = 0
bar = 1
获取翻译为
from enum import Enum, unique
class MyEnum(Enum):
foo = 0
bar = 1
MyEnum = unique(MyEnum)
示例2 - 基于类的装饰器:
我将使用问题中的装饰器。它是作为一个类写的。
class MyClass:
@DocumentMemberAttribute()
def Method1():
pass
@DocumentMemberAttribute(True)
def Method2():
pass
获取翻译为
class MyClass:
def Method1():
pass
Method1 = DocumentMemberAttribute()(Method1)
def Method2():
pass
Method2 = DocumentMemberAttribute(True)(Method2)
在将Method1
作为参数传递给班级之前,请注意空括号。 __call__
方法。这些是初始化程序(__init__
)括号。因此,当传递True作为参数时,这些括号将填充Method2
。
总之:
PyCharm用户请注意:
查看彩色@
标志: