Search code examples
pythonpropertiesgetter-setter

nesting of properties vs setters and getters in python


class OurAtt():
    def __init__(self):
        self.Log = False

    def setLog(self):
        self.Log = True

    def clearLog(self):
        self.Log = False

class OurClass(object):

    def __init__(self):
        self.__OurAtt = OurAtt()

    @property
    def OurAtt(self):
        return self.__OurAtt

    @OurAtt.setter
    def OurAtt(self, val):
       raise Exception("can't modify the attribute" )

x = OurClass()
x.OurAtt.setLog()
print x.OurAtt.Log  # print True
x.OurAtt.Log = False
print x.OurAtt.Log  # sets to False Aim set this through function call     x.OurAtt.setLog()  I want to restrict the access, something like private variable.

Final aim is Log should be the attribute of OurAttr and should be protected by getter and setters or properties. Its like nesting of properties. and hierarchy should be maintained like object.OurAttr.Log

I researched and got the following link.

Python: multiple properties, one setter/getter

But It is not hitting my aim.

I am actually new to getter, setter and properties. Thanks in advance


Solution

  • I believe you are over-complicating the issue. If you want to prevent access to the attributes of OurAtt, the @property decorator should be used withing OurAtt. Instances of the OurAtt class will implement this protected-access behavior always, including when they are members of OurClass. You don't need to do anything with the @property decorator in OurClass unless you want to prevent modifying members of that class.

    This, I think, does what you are trying to accomplish. It runs under 2.7 - if you are using an earlier version your mileage may vary.

    class OurAttr(object):
        def __init__(self):
            self._log = False
    
        @property
        def log(self):
            return self._log
    
        @log.setter
        def log(self, value):
            raise AttributeError("Cannot set 'log' attribute directly.")
    
        @log.deleter
        def log(self):
            raise AttributeError("Cannot delete 'log' attribute directly.")
    
        def setLog(self):
            self._log = True
            print "Log is", self._log
    
        def clearLog(self):
            self._log = False
            print "Log is", self._log
    
    class OurClass(object):
        def __init__(self):
            self.OurAttr = OurAttr()
    
    oc = OurClass()
    oc.OurAttr.setLog()
    oc.OurAttr.clearLog()
    oc.OurAttr.log = False   # Raises exception
    

    Output is:

    $ python2.7 test.py
    Log is True
    Log is False
    Traceback (most recent call last):
      File "test.py", line 33, in <module>
        oc.OurAttr.log = False
      File "test.py", line 11, in log
        raise AttributeError("Cannot set 'log' attribute directly.")
    AttributeError: Cannot set 'log' attribute directly.