问题描述
class MyClass:
def __init__(self,*args,**kwargs):
self.lst = [MyClass.method1]
def method1(self):
pass
def method2(self):
pass
我将这个类扩展为派生类:
class MyDerivedClass(MyClass):
def __init__(self,**kwargs):
self.lst = [MyDerivedClass.method1,MyDerivedClass.method3]
def method3(self):
pass
def method4(self):
pass
列表lst
包含特定的方法选择:在基类中,它应该只包含method1,而在派生类中只包含method1和method3。我想自动创建 lst
,而不必覆盖 __init__
(原因是,在我的情况下,覆盖 __init__
非常复杂,并且有很多方法)。有没有办法用这样的装饰器来做到这一点?
@might_have_to_use_class_decorator?
class MyClass:
def __init__(self,**kwargs):
lst = #automatically compile marked methods -> [method1]
@mark_this_method
def method1(self):
pass
def method2(self):
pass
@might_have_to_use_class_decorator?
class MyDerivedClass(MyClass):
def __init__(self,**kwargs):
lst = # automatically compiled,[method1,method3]
@mark_this_method
def method3(self):
pass
def method4(self):
pass
有没有办法使用装饰器来做到这一点,也许是通过装饰我们的类?
解决方法
正如@juanpa.arrivillaga 建议的那样,简单的方法是在类变量中保留方法名称列表,但如果这不适合您,您确实可以使用装饰器来实现。
诀窍是使用方法装饰器在方法对象上动态分配一个属性,然后使用类装饰器枚举所有方法。
def mark_method(method):
method.is_marked = True
return method
def class_with_marked_methods(cls):
parent_marked_methods = getattr(cls,"marked_methods",())
marked_methods = list(parent_marked_methods)
for method in cls.__dict__.values():
if getattr(method,"is_marked",False):
marked_methods.append(method)
cls.marked_methods = tuple(marked_methods)
return cls
@class_with_marked_methods
class MyClass:
@mark_method
def method1(self):
pass
def method2(self):
pass
@class_with_marked_methods
class MyDerivedClass(MyClass):
@mark_method
def method3(self):
pass
def method4(self):
pass
print([method.__name__ for method in MyDerivedClass.marked_methods])
# prints ["method1","method3"]
我已将 marked_methods
属性设为元组,以便在创建后无法更改,但它也可以轻松成为列表。