【问题标题】:How to write to an abstract property in Python 3.4+如何在 Python 3.4+ 中写入抽象属性
【发布时间】:2017-06-05 20:07:34
【问题描述】:

在 Python 3.6 中,假设我有一个抽象类 MyAbstractClass

from abc import ABC, abstractmethod

class MyAbstractClass(ABC):

    @property
    @abstractmethod
    def myProperty(self):
        pass

还有一个类MyInstantiatableClass 继承自它。那么如何在从此类中实例化对象时写入属性myProperty?我希望能够设置和获取myProperty。下面不行。

from MyAbstractClass import MyAbstractClass

class MyInstantiatableClass(MyAbstractClass):
    def __init__(self, desiredValueOfMyProperty):
        ????

    @myProperty.setter
    def myProperty(self, desiredValueOfMyProperty): # value coming from __init__
        self._myProperty = desiredValueOfMyProperty

还有一个主要功能,比如说,

from MyInstantiatableClass import MyInstantiatableClass

def main():
    MyInstantiatableClass(3) # 3 is the desiredValueOfMyProperty for this instantiation
    MyInstantiatableClass(5) # 5 is the desiredValueOfMyProperty for this instantiation

【问题讨论】:

  • 你是在实现only setter,没有getter吗?
  • 我希望能够在MyInstantiatableClass 设置和获取myProperty
  • 以与通常相同的方式定义属性。

标签: python python-3.x inheritance abstract-class


【解决方案1】:

这里似乎存在差异;使用@property@abstractmethod 似乎不会强制从您的abc 继承的类需要同时定义settergetter。使用这个:

@property
@abstractmethod
def myProperty(self):
    pass

@myProperty.setter
@abstractmethod
def myProperty(self):
    pass

然后只为类中的getter 提供实现并允许实例化:

@property
def myProperty(self):
    return self._myProperty

这是因为ABC的命名空间中只出现了一个名字(myProperty),在基类中重写时,只需要定义这个名字。

有一种方法可以强制执行它。您可以创建单独的抽象方法并直接将它们传递给property

class MyAbstractClass(ABC):

    @abstractmethod
    def getProperty(self):
        pass

    @abstractmethod
    def setProperty(self, val):
        pass

    myAbstractProperty = property(getProperty, setProperty)

现在为这个 abc 提供一个实现需要 gettersetter 都有一个实现(在 MyAbstractClass 命名空间中被列为 abstractmethods 的两个名称都需要一个实现):

class MyInstantiatableClass(MyAbstractClass):

    def getProperty(self):
        return self._Property

    def setProperty(self, val):
        self._Property = val
    myAbstractProperty = property(getProperty, setProperty)

实现它们与任何旧属性完全相同。没有区别。

【讨论】:

  • 抽象属性不需要使用.setter,在抽象属性上指定.setter不会强制具体实现有一个setter或类似的东西。
  • @user2357112 我没想到,这是真的。您显然可以通过将abstractmethods 直接传递给property 来强制实现定义两者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多