我正在尝试使用抽象方法(addfeature)实现抽象超类(Base),Child类将覆盖它。
from lxml.builder import ElementMaker
from abc import ABCMeta, abstractmethod
class Base(object):
__metaclass__ = ABCMeta
ns = "http://www.foo.com/bar"
em = ElementMaker(namespace=ns, nsmap={'bar': ns})
@abstractmethod
def addfeature(self):
pass
class Child(Base):
def addfeature(self):
pass
child_instance = Child()
此代码无法使用
“TypeError:无法使用abstract实例化抽象类Child 方法em“
为什么呢? em应该是一个类属性,而不是一个方法(当然不是一个抽象方法)
答案 0 :(得分:3)
ABCMeta
使用__isabstractmethod__
属性检查方法是否为抽象方法。 lxml.builder.ElementMaker
动态生成方法(使用__getattr__
);访问__isabstractmethod__
会混淆ABCMeta
。
>>> ns = "http://www.foo.com/bar"
>>> em = ElementMaker(namespace=ns, nsmap={'bar': ns})
>>> em.child_element
<functools.partial object at 0x0000000002B55598>
>>> em.child_element()
<Element {http://www.foo.com/bar}child_element at 0x27a8828>
>>> em.__isabstractmethod__
<functools.partial object at 0x0000000002B55598>
>>> bool(em.__isabstractmethod__)
True
通过将__isabstractmethod__
指定为False
,您可以解决此问题。
class Base(object):
__metaclass__ = ABCMeta
ns = "http://www.foo.com/bar"
em = ElementMaker(namespace=ns, nsmap={'bar': ns})
em.__isabstractmethod__ = False # <-----
@abstractmethod
def addfeature(self):
pass