How to know if an object has an attribute in Python

前端 未结 14 2090
无人及你
无人及你 2020-11-22 12:19

Is there a way in Python to determine if an object has some attribute? For example:

>>> a = SomeClass()
>>> a.someProperty = value
>>         


        
相关标签:
14条回答
  • 2020-11-22 12:55

    Try hasattr():

    if hasattr(a, 'property'):
        a.property
    

    EDIT: See zweiterlinde's answer below, who offers good advice about asking forgiveness! A very pythonic approach!

    The general practice in python is that, if the property is likely to be there most of the time, simply call it and either let the exception propagate, or trap it with a try/except block. This will likely be faster than hasattr. If the property is likely to not be there most of the time, or you're not sure, using hasattr will probably be faster than repeatedly falling into an exception block.

    0 讨论(0)
  • 2020-11-22 12:56

    I think what you are looking for is hasattr. However, I'd recommend something like this if you want to detect python properties-

    try:
        getattr(someObject, 'someProperty')         
    except AttributeError:
        print "Doesn't exist"
    else
        print "Exists"
    

    The disadvantage here is that attribute errors in the properties __get__ code are also caught.

    Otherwise, do-

    if hasattr(someObject, 'someProp'):
        #Access someProp/ set someProp
        pass
    

    Docs:http://docs.python.org/library/functions.html
    Warning:
    The reason for my recommendation is that hasattr doesn't detect properties.
    Link:http://mail.python.org/pipermail/python-dev/2005-December/058498.html

    0 讨论(0)
  • 2020-11-22 12:57

    hasattr() is the right answer. What I want to add is that hasattr() can also be used well in conjunction with assert (to avoid unnecessary if statements and make the code more readable):

    assert hasattr(a, 'property'), 'object lacks property' 
    

    As stated in another answer on SO: Asserts should be used to test conditions that should never happen. The purpose is to crash early in the case of a corrupt program state.

    0 讨论(0)
  • 2020-11-22 13:01

    EDIT:This approach has serious limitation. It should work if the object is an iterable one. Please check the comments below.

    If you are using Python 3.6 or higher like me there is a convenient alternative to check whether an object has a particular attribute:

    if 'attr1' in obj1:
        print("attr1 = {}".format(obj1["attr1"]))
    

    However, I'm not sure which is the best approach right now. using hasattr(), using getattr() or using in. Comments are welcome.

    0 讨论(0)
  • 2020-11-22 13:02

    Here's a very intuitive approach :

    if 'property' in dir(a):
        a.property
    
    0 讨论(0)
  • 2020-11-22 13:02

    Another possible option, but it depends if what you mean by before:

    undefined = object()
    
    class Widget:
    
        def __init__(self):
            self.bar = 1
    
        def zoom(self):
            print("zoom!")
    
    a = Widget()
    
    bar = getattr(a, "bar", undefined)
    if bar is not undefined:
        print("bar:%s" % (bar))
    
    foo = getattr(a, "foo", undefined)
    if foo is not undefined:
        print("foo:%s" % (foo))
    
    zoom = getattr(a, "zoom", undefined)
    if zoom is not undefined:
        zoom()
    

    output:

    bar:1
    zoom!
    

    This allows you to even check for None-valued attributes.

    But! Be very careful you don't accidentally instantiate and compare undefined multiple places because the is will never work in that case.

    Update:

    because of what I was warning about in the above paragraph, having multiple undefineds that never match, I have recently slightly modified this pattern:

    undefined = NotImplemented

    NotImplemented, not to be confused with NotImplementedError, is a built-in: it semi-matches the intent of a JS undefined and you can reuse its definition everywhere and it will always match. The drawbacks is that it is "truthy" in booleans and it can look weird in logs and stack traces (but you quickly get over it when you know it only appears in this context).

    0 讨论(0)
提交回复
热议问题