类属性被认为是python 2.7中的抽象方法-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: Can’t instantiate abstract class Child with abstract
methods em”

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

解决方法:

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
上一篇:SQl语句查询性能优化


下一篇:python-使用lxml处理请求中的html. TypeError:无法腌制_ElementUnicodeResult对象