python - 定义@property

标签 python python-2.7 properties abstract-class abc

我在具体类中使用 @property 定义 getter 时遇到问题。这是Python代码:

from abc import ABCMeta, abstractproperty

class abstract(object):
    __metaclass__ = ABCMeta

    def __init__(self, value1):
        self.v1 = value1

    @abstractproperty
    def v1(self):
        pass

class concrete(abstract):
    def __init__(self, value1):
        super(concrete, self).__init__(value1)

    @property
    def v1(self):
        return self.v1

然后测试代码并得到此错误:

test_concrete = concrete("test1")
test_concrete.v1

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-190-eb896d7ec1c9> in <module>()
----> 1 test_concrete = concrete("test1")
      2 test_concrete.v1

<ipython-input-189-bf15021022d3> in __init__(self, value1)
     11 class concrete(abstract):
     12     def __init__(self, value1):
---> 13         super(concrete, self).__init__(value1)
     14 
     15     @property

<ipython-input-189-bf15021022d3> in __init__(self, value1)
      3 
      4     def __init__(self, value1):
----> 5         self.v1 = value1
      6 
      7     @abstractproperty

AttributeError: can't set attribute

基本上我打算将 v1 设置为只读属性。

我习惯于对属性及其 getter 函数使用相同的名称,但如果该类继承自抽象类,我似乎无法做到这一点。

我找到了一种解决方法,将 getter 函数 v1 使用不同的名称作为 get_v1:

class abstract(object):
    __metaclass__ = ABCMeta

    def __init__(self, value1):
        self.v1 = value1

    @abstractproperty
    def get_v1(self):
        pass

class concrete(abstract):
    def __init__(self, value1):
        super(concrete, self).__init__(value1)

    @property
    def get_v1(self):
        return self.v1

这个问题有更好的解决方法吗?

最佳答案

您的问题与抽象类无关。这是一个命名空间问题;属性对象和实例属性占用相同的命名空间,实例属性和属性不能同时使用完全相同的名称。

您正在尝试使用 self.v1 = ... 访问属性,并且 v1 并不是神奇的实例属性,只是因为您通过实例上的方法访问它,该方法始终将是属性对象。

同样,你的属性 getter 将导致无限循环:

@property
def v1(self):
    return self.v1

因为 self.v1 属性对象,而不是实例属性。

对实际存储使用不同的名称:

def __init__(self, value1):
    self._v1 = value1

@property
def v1(self):
    return self._v1

请注意,在 Python 中不能拥有真正的私有(private)属性(就像在 C# 或 Java 中一样);名称上的前导下划线只是一种约定,坚定的编码人员始终可以直接访问您的实例状态。 property 对象不会改变这一点。

关于python - 定义@property,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31961914/

相关文章:

python - 或在 Python 的命令行上使用带有两个变量的 argparse 函数

python - Scrapy 只处理 iterable 中的前 10 个请求

python - 使用另一个 cython 模块导入 cython 模块时 undefined symbol

python - 为什么 instance.attribute = value 可以工作,而 __set__ 方法没有在属性中实现?

Python 异步网络服务调用

python - 在输入提示中启用箭头键导航

python - SocketServer.TCPSocket 适用于 stock python,但不适用于使用更新的 OpenSSL 针对 MSVCRT100 编译的 python

python - 如何将 Maya 节点层次结构存储到 Python 字典中

reference - WiX 属性引用另一个属性

java - JavaFX 中的 BigInteger 属性是什么?