Why does `getattr` not support consecutive attribute retrievals?

后端 未结 7 1384
梦如初夏
梦如初夏 2021-02-01 01:53
class A(): pass

a = A()
b = A()

a.b = b
b.c = 1

a.b     # this is b
getattr(a, \"b\") # so is this

a.b.c   # this is 1   
getattr(a, \"b.c\") # this raises an Attrib         


        
7条回答
  •  误落风尘
    2021-02-01 02:17

    Python's built-in reduce function enables the functionality you're looking for. Here's a simple little helper function that will get the job done:

    class NoDefaultProvided(object):
        pass
    
    def getattrd(obj, name, default=NoDefaultProvided):
        """
        Same as getattr(), but allows dot notation lookup
        Discussed in:
        http://stackoverflow.com/questions/11975781
        """
    
        try:
            return reduce(getattr, name.split("."), obj)
        except AttributeError, e:
            if default != NoDefaultProvided:
                return default
            raise
    

    Test proof;

    >>> getattrd(int, 'a')
    AttributeError: type object 'int' has no attribute 'a'
    
    >>> getattr(int, 'a')
    AttributeError: type object 'int' has no attribute 'a'
    
    >>> getattrd(int, 'a', None)
    None
    
    >>> getattr(int, 'a', None)
    None
    
    >>> getattrd(int, 'a', None)
    None
    
    >>> getattrd(int, '__class__.__name__')
    type
    
    >>> getattrd(int, '__class__')
    
    

提交回复
热议问题