Home > Software engineering >  Object has no attribute error when I name attribute with double underscores
Object has no attribute error when I name attribute with double underscores

Time:12-29

I am trying to group all Patient objects by their surnames.

My code:

class Patient:
    def __init__(self, first_name, surname, age, mobile, postcode):
        self.__first_name = first_name
        self.__surname = surname
        self.__doctor = "None"
        self.__age = age
        self.__mobile = mobile
        self.__postcode = postcode
        self.__symptoms = ""
        
    def full_name(self) :
        return "{} {}".format(self.__first_name, self.__surname)
        
    def __str__(self):
        return f'{self.full_name():^20}|{self.__doctor:^6}|{self.__age:^4}|{self.__mobile:^15}|{self.__postcode:^10}'
    
patients = [Patient('Sara','Cath', 20, '07012345678','B1 234'),
            Patient('Mike','Abe', 37,'07555551234','L2 2AB'), 
            Patient('Daivd','Barr', 15, '07123456789','C1 ABC'), 
            Patient('Gerald','Abe', 21, '07012345678','L2 2AB'), 
            Patient('Sara','Abe', 19, '07012345678','L2 2AB'), 
            Patient('Jane','Barr', 35, '07123456789','C1 ABC')]

patients.sort(key=lambda y: y.__surname)
print(patients[0])
print(patients[1])
print(patients[2])
print(patients[3])
print(patients[4])
print(patients[5])
print()
newPat = sorted(patients, key=lambda y: y.__surname)
print(newPat[0])
print(newPat[1])
print(newPat[2])
print(newPat[3])
print(newPat[4])
print(newPat[5])

My code has the surname attribute self.__surname = surname in the __init__ function, the full_name function and in both sorting functions, but when I try to run it gives me the AttributeError: 'Patient' object has no attribute '__surname'

Error:

File "c:\users\mundane\downloads\pythonfiles\files\untitled0.py", line 25, in <lambda>
    patients.sort(key=lambda y: y.__surname)

AttributeError: 'Patient' object has no attribute '__surname'

If I replace each of the four .__surname with literally anything else - like .xyzsurname - it works and correctly prints:

      Mike Abe      | None | 37 |  07555551234  |  L2 2AB  
     Gerald Abe     | None | 21 |  07012345678  |  L2 2AB  
      Sara Abe      | None | 19 |  07012345678  |  L2 2AB  
     Daivd Barr     | None | 15 |  07123456789  |  C1 ABC  
     Jane Barr      | None | 35 |  07123456789  |  C1 ABC  
     Sara Cath      | None | 20 |  07012345678  |  B1 234  

      Mike Abe      | None | 37 |  07555551234  |  L2 2AB  
     Gerald Abe     | None | 21 |  07012345678  |  L2 2AB  
      Sara Abe      | None | 19 |  07012345678  |  L2 2AB  
     Daivd Barr     | None | 15 |  07123456789  |  C1 ABC  
     Jane Barr      | None | 35 |  07123456789  |  C1 ABC  
     Sara Cath      | None | 20 |  07012345678  |  B1 234 

Is there anyway for me to keep the double underscore for the attribute by using another way to order a list of objects?

CodePudding user response:

you are actually trying to access an attribute called __surname, which does not exist in the Patient class. To access the attribute __surname, you should use the mangled name _Patient__surname.

# patients.sort(key=lambda y: y.__surname)
patients.sort(key=lambda y: y._Patient__surname)
print(patients[0])
print(patients[1])
print(patients[2])
print(patients[3])
print(patients[4])
print(patients[5])
print()
# newPat = sorted(patients, key=lambda y: y.__surname)
newPat = sorted(patients, key=lambda y: y._Patient__surname)

print(newPat[0])
print(newPat[1])
print(newPat[2])
print(newPat[3])
print(newPat[4])
print(newPat[5])

can fix your problem.

  • Related