3

我正在尝试使用抽象方法(addfeature)实现一个抽象超类(Base),子类将覆盖该方法。

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:无法使用抽象方法 em 实例化抽象类 Child”

为什么?em 应该是类属性,而不是方法(当然也不是抽象方法)

4

1 回答 1

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
于 2014-12-18T00:03:31.483 回答