如何自动;登记册;python类中作为列表类变量的方法?
定义Python类时,我希望使用decorator将它的一些方法注册到类变量列表中。下面是一个不正确的python示例,它概述了我要查找的内容:如何自动;登记册;python类中作为列表类变量的方法?,python,class,decorator,Python,Class,Decorator,定义Python类时,我希望使用decorator将它的一些方法注册到类变量列表中。下面是一个不正确的python示例,它概述了我要查找的内容: class MyClass: dangerous_methods = [] @classmethod def dangerous_method(cls, func): cls.dangerous_methods.append(func) return func @MyClass.da
class MyClass:
dangerous_methods = []
@classmethod
def dangerous_method(cls, func):
cls.dangerous_methods.append(func)
return func
@MyClass.dangerous_method
def incinerate(self):
pass
def watch_tv(self):
pass
@MyClass.dangerous_method
def stab(self):
pass
def print_dangerous_methods(self):
print(self.dangerous_methods)
obj = MyClass()
obj.print_dangerous_methods()
预期输出为
[<function MyClass.incinerate at 0x000001A42A629280>, <function MyClass.stab at 0x000001A42A629281>]
[,]
有没有可能在不过度折磨Python的情况下实现这一点?这是实现这一点的一种方法:
class-MyClass:
定义初始化(自):
self.u方法=[]
def危险_方法(func):
def内部(自):
self.hazardous_methods.append(func)
返回函数(自身)
返回内部
@危险法
def焚烧(自):
打印('已调用焚化!')
通过
def watch_tv(自动):
打印('Watch_tv called!')
通过
@危险法
def stab(自我):
打印('Stab called!')
通过
def打印方法(自我):
打印(自我危险的打印方法)
obj=MyClass()
焚化
#焚化呼叫!
obj.看电视
#看电视!
obj.stab()
#刺杀呼叫!
焚化
#焚化呼叫!
对象打印方法()
# [, ]
只需注意,通过这种方式,函数只在调用一次后才会添加到列表中,并且存在函数多次添加到列表中的风险。但是,如果您知道要将某些函数添加到列表中,并且它们是常量,则可以在构建对象时简单地添加它们:
class-MyClass:
定义初始化(自):
self.danger_方法=[self.infense,self.stab]
def焚烧(自):
打印('已调用焚化!')
通过
def watch_tv(自动):
打印('Watch_tv called!')
通过
def stab(自我):
打印('Stab called!')
通过
def打印方法(自我):
打印(自我危险的打印方法)
obj=MyClass()
对象打印方法()
# [, ]
您真正想做的就是在方法上设置危险
。请记住,python函数和方法是一流的对象,您可以对它们设置任意属性
def print_dangerous_methods(cls):
""" yes, you could also return a list """
for name in dir(cls):
f = getattr(cls, name)
if callable(f) and getattr(f, "dangerous", False):
print(name)
def dangerous(func):
setattr(func, "dangerous", True)
return func
class MyClass:
@dangerous
def incinerate(self):
print("incinerate")
def watch_tv(self):
pass
@dangerous
def stab(self):
return "you've been stabbed"
class_born_dangerous = print_dangerous_methods
print("\non instance")
obj = MyClass()
print_dangerous_methods(obj)
print("\non class")
print_dangerous_methods(MyClass)
print("\nand yes, they work")
obj.incinerate()
print (obj.stab())
print("\nas a classmethod")
obj.class_born_dangerous()
输出:
如果要推广此方法并设置任意属性,则需要设置参数化装饰器:
def annotate_func(**kwds):
"""set arbitrary attributes"""
def actual_decorator(func):
for k, v in kwds.items():
setattr(func, k, v)
return func
return actual_decorator
您将按如下方式使用:
@annotate_func(dangerous=1,range=1000)
def shoot(self, times):
for i in range(0, times):
print("bang!")
下面的代码片段与您描述的完全相同 请注意,
print\u危险的\u方法
被声明为类方法,因为它实际上就是这样的(它应用于类,而不是某个实例)。这意味着即使不创建实例也可以调用它
class-MyClass:
def危险_方法(meth):
冰毒是否危险=正确
返回冰毒
@危险法
def焚烧(自):
通过
def watch_tv(自动):
通过
@危险法
def stab(自我):
通过
@类方法
def打印方法(cls):
印刷品([
用冰毒换冰毒[
目录(cls)中methname的getattr(cls,methname)
]
如果getattr(冰毒,“是否危险”,错误)
])
MyClass.print\u方法()
因此,您现在有了一个方法列表!你想有一个方法名列表吗?我包含的代码实际上不起作用,所以我还没有一个方法列表。我也需要名称,但是如果我有方法列表,那么我也可以使用。_uname_;来获取名称。
@annotate_func(dangerous=1,range=1000)
def shoot(self, times):
for i in range(0, times):
print("bang!")