我在具体类中使用@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将导致无限循环:
因为
self.v1
是属性对象,而不是实例属性。你知道吗为实际存储使用不同的名称:
请注意,在Python中不能有真正私有的属性(就像在C#或Java中一样);名称上的前导下划线只是一种约定,确定的编码者始终可以直接访问实例状态。
property
对象不会改变这一点。你知道吗相关问题 更多 >
编程相关推荐