How to restrict the creation of an attribute, outside its class/sub-class?
__all__ = ["Employee","Salary","Wage"]
##################################################################################################
class Person(object):
def __init__(self,fname,lname,gender):
self.__setfname(fname) # "We are all adults." vs. "Name mangling."
self.__setlname(lname)
self.__setgender(gender)
def __setfname(self,fname): self.__fname = fname
def __setlname(self,lname): self.__lname = lname
def __setgender(self,gender): self.__gender = gender
def getname(self): return "{} {}".format(self.__fname,self.__lname)
def getformattedname(self):
if(self.__gender.lower() == "m"):
return "Mr. {}".format(self.getname())
if(self.__gender.lower() == "f"):
return "Ms. {}".format(self.getname())
if(self.__gender.lower() == ""):
return "{}".format(self.getname())
class Payment(object):
def __init__(self,amount,currency="INR"): # currency="USD"
self.__setamount(amount)
self.__setcurrency(currency)
def __setamount(self,amount): self.__amount = amount
def __setcurrency(self,currency): self.__currency = currency
def getamount(self): return "{}".format(self.__amount)
def getformattedamount(self): return "{} {}".format(self.getamount(),self.__currency)
##################################################################################################
##################################################################################################
class Employee(Person):
def __init__(self,fname,lname,gender): super(Employee,self).__init__(fname,lname,gender)
def __str__(self): return self.getformattedname()
class Salary(Payment):
def __init__(self,amount,currency="INR"): super(Salary,self).__init__(amount,currency)
def __str__(self): return self.getformattedamount()
class Wage(Payment):
def __init__(self,amount,currency="INR"): super(Wage,self).__init__(amount,currency)
def __str__(self): return self.getformattedamount()
##################################################################################################
I'm OK with this:
e1._Person__fname = "Spam"
s1._Payment__amount = "1000000000000000"
but the following code creates new attributes:
e1.fname = "New"
s1.amount = -10
import re
from com.example.model import Employee,Salary,Wage
def printzip(l1,l2): print(list(zip([str(e) for e in l1],[str(e) for e in l2])))
(e1,e2) = (Employee("Sandeep","Mehta","m"),Employee("Varsha","Mehta","f"))
(s1,s2) = (Salary(3000,"USD"),Salary(3000,"USD"))
printzip([e1,e2],[s1,s2])
e1.fname = "New"
s1.amount = -3000
e1._Person__fname = "Spam"
s1._Payment__amount = "3000000000000000"
for e in enumerate([e for e in dir(e1) if not (re.search(r"^__.*__$",e))]): print(e)
for e in enumerate([e for e in dir(s1) if not (re.search(r"^__.*__$",e))]): print(e)
printzip([e1],[s1])

Do not try to do this. It's not your business what someone else does with your class. You should document what attributes are expected to be available, and if someone wants to abuse it that's their problem, not yours.
"We're all consenting adults here" is the Pythonic philosophy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With