Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 实现抽象属性,而无需在子对象中重新定义_Python_Python 3.x_Class_Abstract Class_Abc - Fatal编程技术网

Python 实现抽象属性,而无需在子对象中重新定义

Python 实现抽象属性,而无需在子对象中重新定义,python,python-3.x,class,abstract-class,abc,Python,Python 3.x,Class,Abstract Class,Abc,我正在学习abc模块,想知道我想做的事情是否可行 基本上,我为基类创建的每个子类都应该具有相同的\uuuu init\uuuu。基类将有一些需要由子类定义的抽象属性。我想定义这些抽象属性,而不必每次都重写整个\uuuu init\uuuu 例如: 我最初试过这样的东西 from abc import ABC,abstractmethod class test(ABC): def __init__(self): pass @property @abstr

我正在学习abc模块,想知道我想做的事情是否可行

基本上,我为基类创建的每个子类都应该具有相同的
\uuuu init\uuuu
。基类将有一些需要由子类定义的抽象属性。我想定义这些抽象属性,而不必每次都重写整个
\uuuu init\uuuu

例如:

我最初试过这样的东西

from abc import ABC,abstractmethod

class test(ABC):

    def __init__(self):
       pass

    @property
    @abstractmethod
    def prop(self):
        pass

class prop_ex(test):

    @property
    def prop(self):
        return "THIS WORKS"
试验

试验

所以我想那会管用的

编辑:

我看我把事情复杂化了。我本可以这么做的

from abc import ABC,abstractmethod

class test(ABC):

    def __init__(self):
        pass

    @property
    @abstractmethod
    def prop(self):
        pass

class prop_ex(test):

    prop = "THIS WORKS"

这样做有问题吗

正如您正确总结的那样,最直接的解决方案是定义一个
抽象属性
,并简单地让子类定义它,根本不需要
\uuuuu init\uuu

我会更进一步,在基类中抛出一个异常,只是为了确保没有对它进行错误的
super()
调用

import abc

class test(abc.ABC):
    @property
    @abc.abstractmethod
    def prop(self):
        raise NotImplementedException()

class prop_ex(test):
    prop = "THIS WORKS"

顺便说一句:你的第一个例子已经对我有用了。另外两种方法不起作用,因为第二种方法试图找到一个名为
prop
局部变量,该变量不存在,第三种方法在类主体中引用
self
,但
self
仅在类的方法/属性中定义,而不是在类主体中定义



此外,这并不能防止子类中的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>被重写,任何子类都可以修改
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。它建议使用
@property@abstractmethod
@Melendowski谢谢。我完全忽略了这一点。我从答案中删除了那一段。我一定是用第一种方法做了一个booboo之类的东西,因为它现在对我有效,事实上它是首选,因为当前的解决方案不保护只读属性,这正是我想要的。
>>> from abc_tests import prop_ex
>>> blah = prop_ex()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "abc_tests.py", line 13, in __init__
    self.prop = prop
NameError: name 'prop' is not defined
from abc import ABC,abstractmethod

class test(ABC):

    def __init__(self):
        pass

    @property
    @abstractmethod
    def prop(self):
        pass

class prop_ex(test):
    self.prop = "THIS WORKS"

    @property
    def prop(self):
        return self._prop
>>> from dunder_tests import prop_ex
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "abc_tests.py", line 39, in <module>
    class prop_ex(test):
  File "abc_tests.py", line 40, in prop_ex
    self.prop = "THIS WORKS"
NameError: name 'self' is not defined
>>> blah = prop_ex()
> abc_tests.py(14)__init__()
-> self.prop = prop
(Pdb) dir(self)
['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', 'prop']
from abc import ABC,abstractmethod

class test(ABC):

    def __init__(self):
        pass

    @property
    @abstractmethod
    def prop(self):
        pass

class prop_ex(test):

    prop = "THIS WORKS"
import abc

class test(abc.ABC):
    @property
    @abc.abstractmethod
    def prop(self):
        raise NotImplementedException()

class prop_ex(test):
    prop = "THIS WORKS"