Class and Methods : Calling variable directly instead of method

class NewList(DQ):
    """
    A Python list with some extras!
    """
    def __init__(self, initial_state):
        self.data = initial_state
        self.calc_length()
    
    def calc_length(self):
        """
        A helper function to calculate the .length
        attribute.
        """
        length = 0
        for item in self.data:
            length += 1
        self.length = length
    
    def append(self, new_item):
        """
        Append `new_item` to the NewList
        """
        self.data = self.data + [new_item]
        self.calc_length()

fibonacci = NewList([1, 1, 2, 3, 5])
print(fibonacci.length)

fibonacci.append(8)
print(fibonacci.length)

In the code above print(fibonacci.length) is called which directly calls the variable under the method instead of calling the method itself, how does it work? Thanks everyone!

Topic : Object Oriented Python (Page 10)

When an object of the NewList class is initialized, the calc_length () method is called

    def __init__(self, initial_state):
        self.data = initial_state
        self.calc_length() # !!!!

. During the execution of this method, the self attribute is created.length

    def calc_length(self):
        """
        A helper function to calculate the .length
        attribute.
        """
        length = 0
        for item in self.data:
            length += 1
        self.length = length # !!!!

This way you can reference the length attribute just like any other class attribute in the future.

2 Likes

The __init__ method is a reserved method, much like if is a reserved keyword.

Given a class that defines the __init__ method, whenever you create an object of that class, whatever is inside __init__ is ran. You can read about this in the documentation:

Try adding a call to print and instantiate an object to verify this.

Moving on, when you run fibonacci = NewList([1, 1, 2, 3, 5]), as was mentioned, the __init__ method will also run, and thus calc_length will run, which will create self.length — the attribute that you end up printing.

You can, if you want, call fibonacci.calc_length. But since it was already ran upon creation and it doesn’t return anything, it will just be running code for no good reason. Try adding the return statement return length at the end of the creation of this method and then run the following:

another_fib = NewList([1,1,2])
print(another_fib.calc_length())

I hope this helps.

1 Like

Since length is an attribute and that length can be executed, does this mean that attribute can execute is a similar way as method?