2

Is it possible to check if an instance of a class has an attribute without (being able to) instantiating the class?

Example:

class A where I lack knowledge about arguments to instantiate:

class A:
    def __init__(self, unkown):
        self.a = 1

checking for attribute a in class A fails:

hasattr(A,'a')
>> False

checking for attribute a in instance of class A would succeed:

hasattr(A(1),'a')
>> True

Is it possible to check for attribute a without instantiating A? Maybe with something different than hasattr?

2
  • 1
    Not possible without changes to your class in any sane way. Depending on context you might want to use a dataclass and then access __dataclass_fields__. Commented Jun 15, 2022 at 9:52
  • self.a is an attribute of an instance of the class and therefore never exists until its class is constructed. A class attribute however can be detected by examination of the class's dict (or with hasattr) without instantiation Commented Jun 15, 2022 at 10:00

2 Answers 2

1

In general this is not possible. You can freely set any attribute on any instance of A at any time. Consider

a = A('foo')
setattr(a, input('attr_name: '), 'bar')

A cannot know what attributes may or may not be set on its instances in the future.

You could do some insane things like parse __init__ if you want to limit the question to attributes set in __init__, but most likely we're having an XY-problem here.

Sign up to request clarification or add additional context in comments.

6 Comments

So the only way is making a a property, right?
@gustavz how about documenting the class? Why do you need to dynamically infer instance attributes at runtime? Regardless of that, going through properties seems valid, but remember that properties and attributes can be deleted from instances at runtime.
@gustavz Adding a property decorator won't help
@gustavz an instance attribute, by definition, cannot exist until there is an instance of the class. Even then, remember that instance attributes can come into being outside of __init__ so you're really asking the impossible
|
0

As it's not possible, a workaround can be making a a property:

class A:
    def __init__(self, unkown):
        self._a = 1
    @property
    def a(self):
        return self._a
        
hasattr(A,'a')
>> True

Just leaving this here in the sense of completeness

6 Comments

This is ambiguous. hasattr is returning True because it sees a function called 'a'. It doesn't know what the purpose of the function is. Try removing the property decorator and you'll see that hasattr will still return True
correct, but as it has the sole purpose of returning _a it does what I want implicitly
I could construct an example where this fails your purpose, but it would be pretty contrived.
If you want to make this more robust, subclass property (e.g. my_attribute_property) and then inspect A for these kinds of properties.
yes that's probably true but my use case is really as simple as this. So this might not be globally true but worth a try in such cases.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.