我有一些类,希望将其方法添加到其他类上.我最初的解决方案是使用mixins,但这可能会有点难看:
class Schedule(Enumerator, Humanizer, Inferer, ...):
...
所以我想,也许我可以使用类装饰器来达到相同的效果.
@enumerator
@humanizer
@inferer
class Schedule(object):
...
这是装饰器功能的示例:
import inspect
def inferer(original_class):
from myproj.lib.inferer import Inferer
methods = inspect.getmembers(Inferer, predicate=inspect.ismethod)
for method in methods:
setattr(original_class, method[0], types.MethodTypes(method[1], original_class))
return original_class
…这似乎将方法和类方法适当地添加到装饰的类中.但是,当我在修饰的类上调用这些添加的方法(或类方法)之一时,会出现一些错误.
对于方法:
>>> Schedule().humanize()
TypeError: unbound method humanize() must be called with Humanizer instance as first argument (got type instance instead)
…这似乎表明这些是作为类方法添加的?
对于类方法:
>>> schedule = Schedule.infer(foo)
TypeError: infer() takes exactly 2 arguments (3 given)
注意推断的定义:
class Inferer(object):
@classmethod
def infer(cls, dates):
...
我添加了一些行来进行推断,以显示调用Schedule.infer()时得到的参数:
cls:
dates:
所以,我的问题是:
装饰器函数出了什么问题,导致这些添加的方法和类方法的行为异常?或者,更好的是,如何修改装饰器函数以正确处理这些添加?
请让我知道我是否可以在任何时候提供任何澄清.
解决方法:
假设这是个好主意.这是您可以实现的一种方法.不过,我不能说我会建议.
def horrible_class_decorator_factory(mixin):
def decorator(cls):
d = cls.__dict__.copy()
bases = tuple([b for b in cls.__bases__ if b != object] + [mixin])
return type(cls.__name__, bases, d)
return decorator
现在您可以执行以下操作:
class Inferer(object):
@classmethod
def foo(cls):
return "bar" + cls.__name__
inferer = horrible_class_decorator_factory(Inferer)
@inferer
class X(object):
pass
X.foo()
"barX"
我和这个评论员在一起.仅仅因为您可以做某事并不意味着您应该做.
标签:python
来源: https://codeday.me/bug/20191031/1977424.html