Search code examples
pythonconstructordatamember

Is writing data members inside ctor more pythonic?


My limited experience in python shows that

class Person:
    def __init__(self):
        self.data: Tuple[int, str] = (5, "M")
        print("DONE")

is more common than

class Person:
    data: Tuple[int, str] = (5, "M")
    def __init__(self):
        print("DONE")

Any reason to favor the first version?


Solution

  • This is creating different attributes, the first one is an instance attribute (unique to each instance of the object), the second a class attribute, that is shared among the objects of this class.

    Here is a quick demo (I changed the attribute to a mutable object):

    from typing import List, Union
    
    class PersonA:
        def __init__(self):
            self.data: List[Union[int, str]] = [5, "M"]
            print("DONE")
            
    class PersonB:
        data: List[Union[int, str]] = [5, "M"]
        def __init__(self):
            print("DONE")
    
    pa1 = PersonA()
    pa2 = PersonA()
    pb1 = PersonB()
    pb2 = PersonB()
    

    Now let's mutate one object and looks at the other:

    >>> pa1.data[0] = 1
    >>> pa2.data
    [5, 'M']  # unchanged, as instance attribute
    
    >>> pb1.data[0] = 1
    >>> pb2.data
    [1, 'M']  # changed as affects all objects of the class