怎样让实例中的选定属性变为只读?
在Python中,我想让一个类的选定实例属性对类外的代码只读。也就是说,外部代码不能直接修改这些属性,唯一的修改方式是通过调用实例的方法。我希望语法能够简洁明了。有什么好的方法吗?(我在下面给出了我目前认为最好的答案…)
6 个回答
2
class C(object):
def __init__(self):
self.fullaccess = 0
self.__readonly = 22 # almost invisible to outside code...
# define a publicly visible, read-only version of '__readonly':
readonly = property(lambda self: self.__readonly)
def inc_readonly( self ):
self.__readonly += 1
c=C()
# prove regular attribute is RW...
print "c.fullaccess = %s" % c.fullaccess
c.fullaccess = 1234
print "c.fullaccess = %s" % c.fullaccess
# prove 'readonly' is a read-only attribute
print "c.readonly = %s" % c.readonly
try:
c.readonly = 3
except AttributeError:
print "Can't change c.readonly"
print "c.readonly = %s" % c.readonly
# change 'readonly' indirectly...
c.inc_readonly()
print "c.readonly = %s" % c.readonly
@readonly
self.readonly = 22
这段代码的输出结果是:
$ python ./p.py
c.fullaccess = 0
c.fullaccess = 1234
c.readonly = 22
无法更改 c.readonly
c.readonly = 22
c.readonly = 23
我真想能这样说
也就是说,在一个属性上使用装饰器。这样会显得非常简洁...
2
下面是具体做法:
class whatever(object):
def __init__(self, a, b, c, ...):
self.__foobar = 1
self.__blahblah = 2
foobar = property(lambda self: self.__foobar)
blahblah = property(lambda self: self.__blahblah)
(假设 foobar
和 blahblah
是你想要设为只读的属性。)在属性名前加两个下划线,可以有效地把它隐藏起来,这样外部就无法访问到这些内部版本。这个方法只适用于从对象继承的新式类,因为它依赖于 property
。
不过……这样做其实挺傻的。把变量设为私有似乎是受到了 C++ 和 Java 的影响。你的用户应该通过你设计好的公共接口来使用你的类,而不是因为你强迫他们这样做。
补充:看起来 Kevin 已经发过类似的内容了。
7
你应该使用 @property
装饰器。
>>> class a(object):
... def __init__(self, x):
... self.x = x
... @property
... def xval(self):
... return self.x
...
>>> b = a(5)
>>> b.xval
5
>>> b.xval = 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute