Python Forum
Modifying Class File/ Name-Mangling
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Modifying Class File/ Name-Mangling
#1
Python 3.9.5
Mac OS

Hi All,

I am working on an assignment and could really use some help. It involves two different files (Customer.py and main.py). The instructions I don't understand are Steps 2 and 3.

This is what I have tried: Every variable in customer.py uses the _variable notation (2 underscores) which I think protects others from assigning something to them. It seems to me that to retrieve the right value the main program would use myCustomer.getEmail() instead of myCustomer.Email but they don't. I believe the answer lies in using the name mangling prevention technique with double underscores for the variables. I have played with this and I'm not getting anywhere.

THESE ARE THE STEPS I DON'T UNDERSTAND:

2) Modify the Class File to take advantage of Name Mangling for the Email Attribute so that the property cannot be modified directly by a consumer of the class.

3) add at least 1 additional attribute to the class and make sure your new attribute takes advantage of Name Mangling.

THIS IS THE CODE (there are two files copies and pasted, customer.py and main.py.

Customer.py file
class Customer:
  __Name=""
  __DateOfBirth="1/1/1900"
  __AccountNumber = "Unassigned"
  #note no name mangling on Email attribute (Accessible from outside)
  Email = "[email protected]"

  #constructor
  def __init__(self,Name,DOB,AccountNum,Email):
    self.__Name = Name
    self.__DateOfBirth=DOB
    self.__AccountNumber = AccountNum
    self.Email = Email

  def getName(self):
    return self.__Name

  def getDOB(self):
    return self.__DateOfBirth

  def getAccountNumber(self):
    return self.__AccountNumber

  def getEmail(self):
    return self.Email

  def setName(self,newName):
    self.__Name = newName

  def setDOB(self,newDOB):
    self.__DateOfBirth = newDOB

  def setAccountNumber(self,newAcctNum):
    self.__AccountNumber = newAcctNum

  def setEmail(self,newEmail):
    self.Email = newEmail


  def __del__(self):
    print("Object instance successfully removed")
main.py file
from Customer import Customer


def Main():
  myCustomer = Customer("Bob","12/12/1982","1090-332","[email protected]")
  print(myCustomer.getName() + " " + str(myCustomer.getDOB()) + " " + str(myCustomer.getAccountNumber()) + " " + myCustomer.getEmail())


  myCustomer.Email = "THIS IS A BAD EMAIL ADDRESS" #WORKS
  print(myCustomer.getName() + " " + myCustomer.getDOB() + " " + myCustomer.getAccountNumber() + " " + myCustomer.Email)
  
  myCustomer.AccountNumber = "BAD Account Number" #Doesnt Work...OR DOES IT ?
  print(myCustomer.getAccountNumber()) #OLD Account Number still in tact

  print(myCustomer.AccountNumber)

  #python can be confusing in this regard. BUT our internal data IS still safe Except for the Email that does NOT use Name Mangling
  print(myCustomer.getName() + " " + myCustomer.getDOB() + " " + myCustomer.getAccountNumber() + " " + myCustomer.Email)





Main()
Larz60+ write Jun-10-2021, 01:54 AM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.

Fixed for you this time. Please use bbcode tags on future posts.
Reply
#2
Drop line 6 in customer.py

main.py will now fail at line 9 and line 18 due to the name mangling.

For part 3, see https://www.geeksforgeeks.org/name-mangling-in-python/
Reply
#3
I think you have to replace Email with __Email everywhere. Anyway, it looks like bad Python code with verbose and unnecessary accessor functions where for example properties would be better.
Reply
#4
You had some questions included in the main.py file.
(Jun-09-2021, 11:35 PM)CWillis105 Wrote:
myCustomer.Email = "THIS IS A BAD EMAIL ADDRESS" #WORKS
Yes it works. But it should not work, that is the assignment. So replace "Email" with "__Email" in the Customer.py file as Griboullis suggested.

(Jun-09-2021, 11:35 PM)CWillis105 Wrote:
myCustomer.AccountNumber = "BAD Account Number" #Doesnt Work...OR DOES IT ?
This will work in the sense it gives no error. It adds a name "AccountNumber", not to the class but to the object instance "myCustomer". But this name will not interfere with "__AccountNumber".

(Jun-09-2021, 11:35 PM)CWillis105 Wrote:
print(myCustomer.getAccountNumber()) #OLD Account Number still in tact
Right. The method "getAccountNumber()" uses "__AccountNumber", not the newly added "AccountNumber".

I hope this helps you in understanding what is happening. Don't forget to read the link of Jeffsummers.
Reply
#5
(Jun-10-2021, 12:45 PM)Gribouillis Wrote: Anyway, it looks like bad Python code with verbose and unnecessary accessor functions where for example properties would be better.
As Gribouillis metion this is bad Python code look like your teacher comes for Java and have not bother all to learn how is done in in Python.
It's a little frustrating as seen this stuff many times before.
So the 41 line can be these 6 lines,dos just the same job.
class Customer:
    def __init__(self, name, date_of_birth, account_num, email):
        self.name = name
        self.date_of_birth = date_of_birth
        self.account_num = account_num
        self.email = email
So start of main would be like this see that short code over work the same.
from Customer import Customer

def main():
    my_customer = Customer("Bob", "12/12/1982", "1090-332", "[email protected]")
    print(f'{my_customer.name} {my_customer.date_of_birth} {my_customer.account_num} {my_customer.email}')

main()
Output:
Bob 12/12/1982 1090-332 [email protected]
Still relevant Python Is Not Java written in 2004.
Look at Getters and setters are evil. don’t write getters and setters.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020