我想将对象的所有实例字段转换为属性(仅限 getter),以使它们只读。这些字段可能由子类定义。
我怎样才能做到这一点?
class SomeClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
convert_all_instance_fields_into_properties(self) # implementation ?
我想将对象的所有实例字段转换为属性(仅限 getter),以使它们只读。这些字段可能由子类定义。
我怎样才能做到这一点?
class SomeClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
convert_all_instance_fields_into_properties(self) # implementation ?
可以很容易地使用 python 内置实现只读字段:
class X:
def __init__(self, val):
self.foo = val
def __setattr__(self, key, value):
if not hasattr(self, key): # only for first set
super(X, self).__setattr__(key, value)
else:
raise ValueError
def main():
x = X('bar')
y = X('baz')
assert x.foo == 'bar'
assert y.foo == 'baz'
# raises ValueError
x.foo = 'Raise an error!'
如果要指定哪些字段是只读的
class X:
readonly = ['foo']
def __init__(self, val):
self.foo = val
def __setattr__(self, key, value):
if key in self.readonly and not hasattr(self, key):
super(X, self).__setattr__(key, value)
else:
raise ValueError
Python中没有“私有”之类的东西。如果你想并且足够努力,你可以提取任何东西。
有 2 个级别的半私人:
大多数时候,你只需要一个下划线——人们只有在他们认为他们真的需要它时才会访问它。
在我正在使用的代码中,我看到两个下划线仅用作封装延迟加载的属性的一种方式(一个下划线是“getter”并检查变量是否已加载)。
请记住,即使使用“getter”,您也将返回一个对象,除非您自己返回一个副本。重新思考你的设计,用 Python 思考,而不是“私有”和“getters”。;)
编辑:
好像我误解了这个问题。
标有@property
装饰器的函数将返回不带括号的函数来调用它们(spam.eggs
,而不是spam.eggs()
)并且是“只读的”(你可以这样做bacon = spam.eggs
但不能spam.eggs = bacon
)。
但我的其余评论仍然有效:
eggs.list = []
不会工作,但eggs.list.append("spam")
会!