如果某个类扩展了abc类(抽象基类),那么除非我定义了所有的抽象方法,否则我不能实例化它。但在实现Decorator模式时,我通常只想定义一些抽象的方法,而其他的方法——只需要委托给装饰对象。怎么做?在
我想让下面的代码起作用:
from abc import ABCMeta, abstractmethod
class IElement(object):
__metaclass__ = ABCMeta
@abstractmethod
def click(self):
return
@abstractmethod
def hover(self):
return
# ... more IElement's abstractmethods...
class StandardElement(IElement):
def click(self):
return "click"
def hover(self):
return "hover"
# ... more implemented IElement's methods...
class MyElement(IElement):
def __init__(self, standard_element):
self._standard_element = standard_element
delegate(IElement, standard_element)
def click(self):
return "my click"
assert MyElement(StandardElement()).click() == 'my click'
assert MyElement(StandardElement()).hover() == 'click'
而不是
^{pr2}$为此,我需要实现上面示例中的delegate
方法。如何实施?还可以考虑其他一些方法来为扩展abc类的类提供自动委托。在
p.S。
请不要把继承(class MyElement(StandardElement)
)作为这里的解决方案。。。上面提供了一个示例代码。在我的实际例子中,MyElement和StandardElement是完全不同的东西。不过,我必须使MyElement与StandardElement兼容,因为有时有人应该使用MyElement而不是StandardElement。我真的需要在这里实现“有一个”关系,而不是“是一个”。在
出现此错误是因为类
MyElement
是抽象的(您没有重写方法hover
)。抽象类是至少有一个抽象方法的类。若要解决此错误,应按以下方式添加此方法,例如:如果您想使用
__getattr__
委托许多方法,那么通过abc.abstractmethod
似乎是不可能的,因为__getattr__
会动态地搜索不需要直接运行__getattr__
就无法检查的必要方法。在因此,我建议您将所有方法指定为抽象的(通过
^{pr2}$@abstractmethod
),这些方法肯定会在每个继承的类中被重写,并使用NotImplementedError
实现委派方法。例如:基于Blckknght的回答,我创建了一个python包,扩展了multiple delegates选项和自定义委托属性名的功能。在
看看这里https://github.com/monomonedula/abc-delegation
安装:
pip install abc-delegation
默认情况下,没有自动完成所需委派的方法。委派并不是抽象类的一个显式的部分,所以这并不奇怪。但是,您可以编写自己的委托元类,为您添加缺少的方法:
delegator方法是在一个单独的函数中生成的,因为我们需要一个命名空间,其中
name
在函数创建后不会发生变化。在Python3中,您可以通过给delegator
一个带有默认值的关键字参数来完成__new__
方法中的所有操作,但是在Python2中没有关键字参数,所以这对您不起作用。在以下是如何使用它:
^{pr2}$赋值给
self._delegate
设置元类创建的方法将使用的对象。如果你想的话,你可以用某种方法,但这似乎是最简单的方法。在相关问题 更多 >
编程相关推荐