Python 定义@property

Python 定义@property,python,python-2.7,properties,abstract-class,abc,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

我在具体类中使用
@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

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

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

您正试图使用
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中不能有真正的私有属性(就像在C#或Java中一样);名称上的前导下划线只是一种约定,确定的编码器始终可以直接访问您的实例状态。
属性
对象不会改变这一点。

一种常见做法是命名私有属性,如
\u v1
。您实际上没有为属性提供setter,因此它当前是只读的。此外,您不能将backing属性与属性同名,这没有任何意义。谢谢。当我将属性设置为_v1时,它会起作用。
def __init__(self, value1):
    self._v1 = value1

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