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

Why do the usage of self and Class name differ in this example?

In this piece of code when I write name of the class in the forth line, the account_id differs every time, but when I use self instead, the account_id will be the same number as much as the number of objects, in the reference I’ve learnt from, it said ther’s no difference between using the name of class and key word self in such a situation, but I see in this example that it differs, what’s the reason? Is what I learnt wrong?

class BankAccount():


initial_acount_id = 1000110011
    
def __init__(self, fname, lname, deposit = 0) -> None:
    
    BankAccount.initial_acount_id += 12
    self.account_id = self.initial_acount_id
    self.fname = fname
    self.lname = lname
    self.deposit = deposit
        
fir = BankAccount("ali", 'zarei')
sec = BankAccount('mehrdad', 'rsccz', 50)
thi = BankAccount('sdad', 'ccjkj')

print(fir.account_id)
print(sec.account_id)
print(thi.account_id)

>Solution :

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

I assume you are asking about self.initial_account_id += 12. This does not update the class attribute; it creates a new instance attribute which shadows the class attribute, equivalent to self.initial_account_id = self.initial_account_id + 12. For each new instance, the right-hand occurrence of self.initial_account_id does not yet exist, and so devolves to BankAccount.initial_account_id.

Assuming you don’t define an instance attribute named initial_account_id, then self.account_id = self.initial_account_id will work as expected (the RHS resolves to BankAccount.initial_account_id), but it’s still better to be explicit:

class BankAccount:


    initial_account_id = 1000110011
        
    def __init__(self, fname, lname, deposit = 0) -> None:
        
        BankAccount.initial_account_id += 12
        self.account_id = BankAccount.initial_account_id
        self.fname = fname
        self.lname = lname
        self.deposit = deposit

(That is to say, if you intend to use a class attribute, say so, instead of implicitly accessing it via an instance of the class.)

Even better, remove the (explicit) logic of incrementing the account ID from BankAccount.__init__, and do so implicitly by using an iterator.

from itertools import count


class BankAccount:
    initial_account_id = count(1000110011, 12)
        
    def __init__(self, fname, lname, deposit = 0) -> None:
        # As an aside, self.initial_account_id here would
        # be safe, since we aren't *assigning* to the attribute, only calling
        # one of its mutating methods.
        self.account_id = next(BankAccount.initial_account_id)
        self.fname = fname
        self.lname = lname
        self.deposit = deposit
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