Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Property setter triggers infinite recursion, why?

Using the @property + setter encapsulation, I need a class that raises an exception when someone tries to change the account_number. However, in the __init__ function, I need to set the value. This is the code, it generates recursion.

class SingleBankAccount:
    
    def __init__(self, account_number, account_balance):
        self.account_number = account_number
        self.account_balance = account_balance
        
    @property
    def account_number(self):
        return self.account_number
        
    @account_number.setter
    def account_number(self, number):
    # if there is a number already, raise exception, otherwise set it
        if self.account_number:
            raise AccountException("Someone tried to change the account number!")
        else:
            self.account_number = number

This is the error:

File "main.py", line 17, in account_number

    if self.account_number:

  File "main.py", line 13, in account_number

    return self.account_number

  File "main.py", line 13, in account_number

    return self.account_number

  File "main.py", line 13, in account_number

    return self.account_number

  [Previous line repeated 993 more times]

RecursionError: maximum recursion depth exceeded

Plz help me understand why.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are setting the self.account_number property within the setter. The proper pythonic way is to use a "private" property:

class SingleBankAccount:
    
    def __init__(self, account_number, account_balance):
        self.account_number = account_number
        self.account_balance = account_balance
        
    @property
    def account_number(self):
        return self._account_number
        
    @account_number.setter
    def account_number(self, number):
    # if there is a number already, raise exception, otherwise set it
        if hasattr(self, "_account_number"):
            raise AccountException("Someone tried to change the account number!")
        else:
            self._account_number = number

hasattr is to avoid issues with the property not being set.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading