Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict creation/setting of an attribute

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])

Python IDLE

like image 390
Patt Mehta Avatar asked Dec 29 '25 17:12

Patt Mehta


1 Answers

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.

like image 83
Daniel Roseman Avatar answered Jan 01 '26 05:01

Daniel Roseman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!