Jas*_*n S 10 python oop static class
有没有办法将这个Java代码翻译成Python?
class Foo
{
final static private List<Thingy> thingies =
ImmutableList.of(thing1, thing2, thing3);
}
Run Code Online (Sandbox Code Playgroud)
例如,属于类thingies的不可变私有列表,而不是它的实例.ThingyFoo
我知道如何从这个问题中定义静态类变量Python中的静态类变量,但我不知道如何使它们成为不可变和私有的.
小智 21
在Python中,惯例是使用_属性名称上protected的__前缀来表示和表示前缀private.这不是由语言强制执行的; 程序员应该知道不要编写依赖于非公开数据的代码.
如果你真的想强制实现不变性,可以使用元类[ docs ](类的类).当有人试图修改它时,只需修改__setattr__并__delattr__引发异常,并使其成为tuple(不可变列表)[ docs ].
class FooMeta(type):
"""A type whose .thingies attribute can't be modified."""
def __setattr__(cls, name, value):
if name == "thingies":
raise AttributeError("Cannot modify .thingies")
else:
return type.__setattr__(cls, name, value)
def __delattr__(cls, name):
if name == "thingies":
raise AttributeError("Cannot delete .thingies")
else:
return type.__delattr__(cls, name)
thing1, thing2, thing3 = range(3)
class Foo(object):
__metaclass__ = FooMeta
thingies = (thing1, thing2, thing3)
other = [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
print Foo.thingies # prints "(0, 1, 2)"
Foo.thingies = (1, 2) # raises an AttributeError
del Foo.thingies # raise an AttributeError
Run Code Online (Sandbox Code Playgroud)
Foo.other = Foo.other + [4] # no exception
print Foo.other # prints "[1, 2, 3, 4]"
Run Code Online (Sandbox Code Playgroud)
技术上仍然可以通过遍历类的内部.__dict__属性来修改它们,但这应该足以阻止大多数用户,完全保护Python对象非常困难.
kin*_*all 13
无论如何,你不能用Python做任何一件事,也不能用Java做.
按照惯例,以下划线为前缀的名称被视为私有,不应在实现之外访问,但Python中没有任何内容强制执行此约定.在未来的代码版本中,您可能会在未发出警告的情况下更改可能会更改的实现细节.
你可以通过使用属性使它不可写(与不可变的略有不同),但没有办法使它成为私有 - 这违背了Python的理念.
class Foo(object): # don't need 'object' in Python 3
@property
def thingies(self):
return 'thing1', 'thing2', 'thing3'
f = Foo()
print f.thingies
#('thing1', 'thing2', 'thing3')
f.thingies = 9
#Traceback (most recent call last):
# File "test.py", line 8, in <module>
# f.thingies = 9
#AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
它是否一成不变取决于你的回归; 如果你返回一个可变对象,你可能会改变它并让这些更改显示在实例/类中.
class FooMutable(object):
_thingies = [1, 2, 3]
@property
def thingies(self):
return self._thingies
foo = FooMutable()
foo.thingies.append(4)
print foo.thingies
# [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
这将允许您进行变异thingies,并且因为返回的对象与实例/类中保留的对象相同,所以更改将反映在后续访问中.
与之相比:
class FooMutable(object):
@property
def thingies(self):
return [1, 2, 3]
foo = FooMutable()
foo.thingies.append(4)
print foo.thingies
# [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
由于每次都会返回一个全新的列表,因此对其的更改不会反映在后续访问中.