Python hasattr vs getattr

后端 未结 2 1076
予麋鹿
予麋鹿 2020-12-31 09:48

I have been reading lately some tweets and the python documentation about hasattr and it says:

hasattr(object, name)

The

2条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-31 09:57

    The documentation does not encourage, the documentation just states the obvious. The hasattr is implemented as such, and throwing an AttributeError from a property getter can make it look like the attribute does not exist. This is an important detail, and that is why it is explicitly stated in the documentation. Consider for example this code:

    class Spam(object):
        sausages = False
    
        @property
        def eggs(self):
            if self.sausages:
                return 42
            raise AttributeError("No eggs without sausages")
    
        @property
        def invalid(self):
            return self.foobar
    
    
    spam = Spam()
    print(hasattr(Spam, 'eggs'))
    
    print(hasattr(spam, 'eggs'))
    
    spam.sausages = True
    print(hasattr(spam, 'eggs'))
    
    print(hasattr(spam, 'invalid'))
    

    The result is

    True
    False
    True
    False
    

    That is the Spam class has a property descriptor for eggs, but since the getter raises AttributeError if not self.sausages, then the instance of that class does not "hasattr" eggs.

    Other than that, use hasattr only when you don't need the value; if you need the value, use getattr with 2 arguments and catch the exception, or 3 arguments, the third being a sensible default value.

    The results using getattr() (2.7.9):

    >>> spam = Spam()
    >>> print(getattr(Spam, 'eggs'))
    
    >>> print(getattr(spam, 'eggs'))
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 7, in eggs
    AttributeError: No eggs without sausages
    >>> spam.sausages = True
    >>> print(getattr(spam, 'eggs'))
    42
    >>> print(getattr(spam, 'invalid'))
    Traceback (most recent call last):
      File "", line 1, in 
      File "", line 10, in invalid
    AttributeError: 'Spam' object has no attribute 'invalid'
    >>>
    

提交回复
热议问题