Is there any way to translate this Java code into Python?
class Foo
{
final static private List<Thingy> thingies =
ImmutableList.of(thing1, thing2, thing3);
}
e.g. thingies
is an immutable private list of Thingy
objects that belongs to the Foo
class rather than its instance.
I know how to define static class variables from this question Static class variables in Python but I don't know how to make them immutable and private.
In Python, there is no existence of “Private” instance variables that cannot be accessed except inside an object.
In actual terms (practically), python doesn't have anything called private member variable in Python. However, adding two underlines(__) at the beginning makes a variable or a method private is the convention used by most python code.
Python doesn't have real private variables, so use the __ prefix (two underlines at the beginning make a variable) from PEP 8. Use instance _class-name__private-attribute try to access private variables outside the class in Python.
In Python the convention is to use a _
prefix on attribute names to mean protected
and a __
prefix to mean private
. This isn't enforced by the language; programmers are expected to know not to write code that relies on data that isn't public.
If you really wanted to enforce immutability, you could use a metaclass[docs] (the class of a class). Just modify __setattr__
and __delattr__
to raise exceptions when someone attempts to modify it, and make it a tuple
(an immutable list) [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]
print Foo.thingies # prints "(0, 1, 2)"
Foo.thingies = (1, 2) # raises an AttributeError
del Foo.thingies # raise an AttributeError
Foo.other = Foo.other + [4] # no exception
print Foo.other # prints "[1, 2, 3, 4]"
It would still technically be possible to modify these by going through the class's internal .__dict__
of attributes, but this should be enough to deter most users, it's very difficult to entirely secure Python objects.
You can't do either of those things in Python, not in the sense you do them in Java, anyway.
By convention, names prefixed with an underscore are considered private and should not be accessed outside the implementation, but nothing in Python enforces this convention. It's considered more of a warning that you're messing with an implementation detail that may change without warning in a future version of the code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With