Search code examples
pythonclassmethodssubstitutiongetattr

How to emulate .users.get in Python class?


I want to create a fictive micro-class with attributes .users.get and no having implementation of them inside of the class (I'm planning to use this class as a substitude in MagicMock(spec=This_Class)). I've read about getattr but I've no idea how to implement it right. Maybe you could me to figure it out?

class A(object):
  def __getattr__(self, attr):
    if attr == 'users':
        self.__getattr__(self.users, 'get')
    if attr == 'get':
        return [{'uid': 4444444}]

Solution

  • __getattr__ will only be called if users has not been found. Since you apparently have a self.users it will be found and returned.

    __getattribute__ will be called (almost always) and will allow you to intercept the returned value.

    The best approach imho:

    class A(object):
    
        def __getattribute__(self, attrname):
            try:
                attr = object.__getattribute__(self, attrname)
            except AttributeError as e:
                raise e
    
            if attrname == 'users':
                attr = attr.get()
    
            return attr
    

    Edit according to the comment:

    class A(object):
    
        def __getattr__(self, attrname):
            if attrname == 'users':
                return self
    
            if attrname == 'get'
                return self
    
            raise AttributeError('{} not found'.format(attrname))
    
        def __call__(self)
            return [{'uid': 4444444}]
    

    An attribute cannot return the list you want, because you want to invoke the attribute. That means you have to return self and then self will be invoked as if it were the get method of users and will return the list (with the embedded dict in it)