Search code examples
pythonattributes

In python, should attributes only be accessed by methods?


Here are two examples of classes that handle their attribute differently.

class MyClassA():
    def __init__(self):
        self.my_attribute = 1

class MyClassB():
    def __init__(self):
        self._my_attribute = 1

    def get_my_attribute(self):
        return self._my_attribute

    def set_my_attribute(self, value):
        self._my_attribute = value

Is there a python consensus on which is best practice?


Solution

  • Best practice is to pick the one that meets your needs. If you need someone using your class to use the getter and setter - for example to perform checks, or to take care of required side-effects - then that's what you should do.

    If it's just an attribute that you're happy to have changed by other code (no side-effects) the first solution is fine.

    Note that there's also @property decorators for a nicer way to do the second type - which would be best practice over these get_... and set_... methods:

    class MyClassB():
        def __init__(self):
            self._my_attribute = 1
    
        @property
        def my_attribute(self):
            return self._my_attribute
    
        @my_attribute.setter
        def my_attribute(self, value):
            self._my_attribute = value
    

    Note that adding the _ doesn't actually hide the attribute, it just generates warnings in editors that respect it:

    b = MyClassB()
    print(b.my_attribute)
    b.my_attribute = 10
    print(b.my_attribute)
    print(b._my_attribute)  # generates a warning, but works all the same
    

    Output:

    1
    10
    10