You can use @property
annotations to implement getters and setters à la Java or Ruby. These provide some form of encapsulation while still allowing users of your class to access attributes in a Pythonic way.
Say you have a class with a public-facing name
attribute, but names needed to be under a certain length.
class Foo(object):
def __init__(self, name: str):
if len(name) <= 3:
self.name = name
else:
raise TypeError
In this case, the name
value length is checked at instantiation but not thereafter; you could use a _name
attribute and ugly get_name()
and set_name()
methods, but by using @property
annotations as below, you can do validity checking for the attribute whenever it's set while still letting it be accessed in the conventional Python way, i.e. by means of expressions like foo.name
and foo.name = 'xyz'
.
class Foo(object):
def __init__(self, name: str):
self.name = name
@property
def name(self):
return self._name
@name.setter
def name(self, new_name: str):
if len(new_name) <= 3:
self._name = new_name
else:
raise TypeError
As Idan mentioned, _
-prefixing of private methods/attributes is just a (strongly followed) convention and a user could still mangle the attribute value if they really wanted to, e.g. by foo._name = 'abcdef'
.