class属性在python 2.7中被认为是抽象方法 - abc模块

时间:2014-12-17 23:45:54

标签: python python-2.7 lxml abc

我正在尝试使用抽象方法(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应该是一个类属性,而不是一个方法(当然不是一个抽象方法)

1 个答案:

答案 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