2014-12-17 5 views
3

Я пытаюсь реализовать абстрактный суперкласс (Base) с абстрактным методом (addfeature), который класс Child переопределит.атрибут класса считается абстрактным методом в python 2.7 - модуль abc

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 должен быть атрибутом класса, а не методом (и, конечно, не абстрактным).

ответ

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 
+0

Спасибо за четкое объяснение и решение! –

 Смежные вопросы

  • Нет связанных вопросов^_^