setattr(), getattr()

  1. hasattr(object, name) function:
  2. Determines whether an object has a name attribute or a name method, returns a bool value, returns True with a name attribute, or returns False.

  3. getattr(object, name[,default]) function:
    1. >> Python will call __getattr__method whenever you request an attribute that hasn't already been defined.

      Note that if the attribute is found through the normal mechanism, __getattr__() is not called.

      getattr(object, 'x') is completely equivalent to object.x.

      There are only two cases where getattr can be useful.

    2. You can't write object.x, because you don't know in advance which attribute you want (it comes from a string). Very useful for meta-programming.
    3. You want to provide a default value. object.y will raise an AttributeError if there's no y. But getattr(object, 'y', 5) will return 5.
    4. class User:
          _persist_methods = ['get', 'save', 'delete']
      
      		def __init__(self, persister):
              self._persister = persister
      
      		def __getattr__(self, attribute):
      				if attribute in self._persist_methods:
      						return getattr(self._persister, attribute)
  4. __getattribute__ If you have __getattribute__ method in your class, python invokes this method for every attribute regardless whether it exists or not. Useful if you want to prevent the access of some variables.
  5. IMPORTANT: If your class contain both getattr and getattribute magic methods then __getattribute__ is called first. But if __getattribute__ raises AttributeError exception then the exception will be ignored and __getattr__ method will be invoked.

  6. setattr(object, name, values) function:
  7. Assign a value to an object's property. If the property does not exist, create it before assigning it.

    class X:
        def __init__(self, value1, value2):
            self.__non_private_name_1 = value1
            setattr(self, '__non_private_name_2', value2)
    
    >>> x = X('Hi', 'Bye')
    >>> x.__dict__
    {'_X__non_private_name_1': 'Hi', '__non_private_name_2': 'Bye'}
    class MyTest(object):
    
        def __init__(self, x):
            self.x = x
    
        def __setattr__(self, name, value):
            if name == "device":
                print "device test"
            else:
                super(MyTest, self).__setattr__(name, value)
                # in python3+ you can omit the arguments to super:
                #super().__setattr__(name, value)
    						# OE self.__dict__[name] = value

GitHub great example

>>> # this example uses __setattr__ to dynamically change attribute value to uppercase
>>> class Frob:
...     def __setattr__(self, name, value):
...         self.__dict__[name] = value.upper()
...
>>> f = Frob()
>>> f.bamf = "bamf"
>>> f.bamf
'BAMF'

Note that if the attribute is found through the normal mechanism, __getattr__() is not called. (This is an intentional asymmetry between  __getattr__()  and  __setattr__().) This is done both for efficiency reasons and because otherwise __getattr__() would have no way to access other attributes of the instance.

>>> class Frob:
...     def __init__(self, bamf):
...         self.bamf = bamf
...     def __getattr__(self, name):
...         return 'Frob does not have `{}` attribute.'.format(str(name))
...
>>> f = Frob("bamf")
>>> f.bar
'Frob does not have `bar` attribute.'
>>> f.bamf
'bamf'

If the class also defines __getattr__(), the latter will not be called unless __getattribute__() either calls it explicitly or raises an AttributeError.

>>> class Frob(object):
...     def __getattribute__(self, name):
...         print "getting `{}`".format(str(name))
...         object.__getattribute__(self, name)
...
>>> f = Frob()
>>> f.bamf = 10
>>> f.bamf
getting `bamf`

References

SuperMade with Super