Search code examples
pythonpython-class

Forcing read-only Parameter / property in __init__ class constructor in Python


It might be dumb and repeat question just like Class-level read-only properties in Python, which is hard to understand and implement. But is there any simple way to stop object user to modify class level defined read-only property (not method), just like other languages that simply use "Private" keyword to make it inaccessible? For example in this simple code, I want to have "full_name" property to be set as read-only when user initiates object, and not able to change it once initiated by inner-method.

class Test:
    def __init__(self,fname:str,lname:str):
        self.first_name = fname
        self.last_name = lname
        ## expected to be a read only property "full_name"
        self.full_name = self.__private_fullname(fname,lname)
        
    def __private_fullname(self,name1,name2):
        return name1 + ' ' + name2
   
   
    
 # tester
name = Test('John','Watson')
print(name.full_name)   ## returns 'John Watson'
name.full_name ='someone else'   ## still user can change read-only property
print(f'Now full_name directly changed to "{name.full_name}" by object user')

Solution

  • there is no way at all to define a private variable in python but you can simulate this with (@property) decorator for clean code purpose: something like code below:

    class Test:
        def __init__(self, fname: str, lname: str):
            self.first_name = fname
            self.last_name = lname
            ## expected to be a read only property "full_name"
            self.__full_name = fname + ' ' + lname
        @property
        def full_name(self):
            return self.__full_name
    
    
    # tester
    name = Test('John', 'Watson')
    print(name.full_name)  ## returns 'John Watson'
    # name.full_name = 'someone else'  ## still user can change read-only property
    print(f'Now full_name directly changed to "{name.full_name}" by object user')
    

    if you try to change full_name you get the error like this ->AttributeError: can't set attribute