Search code examples
pythonnaming-conventionssmalltalkaccessor

Naming convention for accessor methods in Python


Q1: Coming from an OO background (Java, Ruby, Smalltalk), what would be the preferred way of naming accessor and mutator methods when writing classes in Python? For example if I have:

class Account :
    def __init__(self, owner) : 
        self.__owner = owner
        self.__amount = 0
    def owner(self) :
        return self.__owner

Should I call my accessor methods after the name of the attribute like owner() to access the private attribute __owner as is custom in languages like Smalltalk and Ruby, or rather call it get_owner which would be the snake-case equivalent of how you would call an accessor in Java. I assume the Java way would be prefered?

Q2: Similar question for mutator methods: should I call them set_owner à la Java or rather something else?

Q3: Final question: if my attributes are public, as in:

class Account :
    def __init__(self, owner) : 
        self.owner = owner
        self.amount = 0

Should I even bother to write accessor and mutator methods for them then, since I can access and assign these attributes from outside the class anyway?


Solution

  • AFAIK private attributes aren't as emphasized in Python as other languages. Every attribute is easily accessed, so dedicated getters/setters that get around "private" attributes is mostly honor system. So this would be the go-to:

    class Account :
        def __init__(self, owner) : 
            self.owner = owner
            self.amount = 0
    
    a = Account("Kim")
    a.owner
    a.amount
    a.owner = "Carol"
    a.amount = 100
    

    Now, people have mentioned properties. That's a way to "fake" nonexistent attributes with getters and setters so you get to still use the attribute syntax x.y = z. It does the same thing as x.set_y(z), so if this aesthetic isn't a concern to you, feel free not to use properties; instance method calls are not any less "Pythonic" than attribute access.

    Properties aren't used in Python to implement privacy, usually. They're used on getters/setters that calculate values on the fly. Units conversion is a good example:

    class Temperature:
        def __init__(self, Kelvin = 0.0):
            self.K = Kelvin
        
        @property
        def C(self):
            return self.K - 273.15
        
        @C.setter
        def C(self, Celsius):
            self.K = Celsius + 273.15
    
        @property
        def F(self):
            return self.C * 9/5 + 32
        
        @F.setter
        def F(self, Fahrenheit):
            self.C = (Fahrenheit - 32) * 5/9
    

    So, instead of storing the same temperature in 3 different units, you store it in Kelvin and use getters/setters to get Celsius or Fahrenheit. Properties just provide the aesthetic symmetry of temp.K, temp.C, temp.F instead of temp.K, temp.getC(), temp.getF().