如何在python中使用abstractproperty装饰器强制子类设置属性?

jav*_*ved 6 python abstract-class python-2.7

我想强制执行一个Child类来设置几个属性(实例变量),以实现我在python 2.7中使用abstractproperty装饰器。这是示例代码:

from abc import ABCMeta, abstractproperty
class Parent(object):
    __metaclass__ = ABCMeta
    @abstractproperty
    def name(self):
        pass

class Child1(Parent):
    pass

class Child2(Parent):
    name = 'test'

class Child3(Parent):
    def __init__(self):
        self.name = 'test'

obj_child1 = Child1()
Run Code Online (Sandbox Code Playgroud)

Child1对象的创建产生了预期的错误。

obj_child2 = Child2()
Run Code Online (Sandbox Code Playgroud)

创建Child2对象的工作正常,因为设置了抽象属性“名称”

然而

 obj_child3 = Child3()
Run Code Online (Sandbox Code Playgroud)

给出TypeError:无法使用抽象方法名称实例化抽象类Child3

我不明白:尽管在初始化 方法中设置了属性“名称” ,但为什么创建Child3对象会引发类型错误。

我的要求是在子类的方法内设置属性。解释child2类有什么问题以及是否有更好的方法来强制子类在方法中设置属性,这将对我有所帮助。提前致谢。

小智 6

一个更简单的解决方案是

class Parent(object):
    name = None
    def __init__(self):
        if self.name == None:
            raise NotImplementedError('Subclasses must define bar')

class Child1(Parent):
    pass

class Child2(Parent):
    name = 'test'

class Child3(Parent):
    def __init__(self)
        self.name = 'test'
Run Code Online (Sandbox Code Playgroud)

obj1 = Child1() 引发 NotImplementedError

obj2 = Child2() 工作正常

obj3 = Child3()工作正常。这是您强制子类设置属性name并从方法设置属性所需的内容。


小智 3

你可以这样做,父类:

class Parent(object):
    __metaclass__ = ABCMeta
    @abstractproperty
   def name(self):
       pass
Run Code Online (Sandbox Code Playgroud)

儿童班:

class Child(Parent):
    name = None
    def __init__(self):
        self.name = 'test'
Run Code Online (Sandbox Code Playgroud)

现在

obj = Child() obj.name

给出“测试”所需的输出。

通过这样做,您可以强制一个类设置父类的属性,并且在子类中您可以通过方法设置它们。这不是您需要的完美解决方案,但已经很接近了。此解决方案的唯一问题是您需要像None在子类中一样定义父级的所有抽象属性,并使用方法来设置它们。