Is there a way to find if a python object has an attribute?

Viewed 863

I'm trying to verify if a python object has an attribute inside the definition of one of its methods, here is some code to clarify :

class A :
    def __init__(self) : 
        self.__a = 5
    def hasAttr(self) : 
        if hasattr(self, '__a'):
            print(True)
        else : 
            print(False)

If I execute the code

x = A()
x.hasAttr()

I get False, I know the reason it doesn't work is that the attribute is virtually private, but I'm not intending to access the attributes outside of the class, I just want to verify if the attribute has been yet definded , I know I can always use :

class A :
    def __init__(self) : 
        self.__a = 5
    def hasAttr(self) : 
        if ('_'+self.__class__.__name__ + '__a') in self.__dict__:
            print(True)
        else : 
            print(False)

But isn't there a more soft way to do it ?

2 Answers

Double underscore variables are name mangled adding the class name in front of the method, so __a becomes _A__a as you rightly identified, hence you get False in the first case.

Similarly you can do hasattr(self, '_'+self.__class__.__name__ + '__a') in the second case

class A :

    def __init__(self) :
        self.__a = 5

    def hasAttr(self) :

        attr_name = f'_{self.__class__.__name__}__a'
        if hasattr(self, attr_name):
            print(True)
        else :
            print(False)

x = A()
x.hasAttr()

Or you can use EAFP approach to try to access the variable, and print True or False accordingly

class A :

    def __init__(self) :
        self.__a = 5

    def hasAttr(self):

        attr_name = f'_{self.__class__.__name__}__a'
        try:
            getattr(self, attr_name)
            print(True)
        except:
            print(False)

x = A()
x.hasAttr()

The output will be True

You can use AttributeError exception to test if you have an attribute:

class A :
    def __init__(self) :
        self.__a = 5
    def hasAttr(self):
        try:
            self.__a
            return True
        except AttributeError:
            return False

x = A()
print(x.hasAttr())

Prints:

True
Related