1

I will get straight to the point. I have been trying to find different ways in which I can check if an instance attribute exists in a method of a class which has not been called from the instance of the class.

Consider the following example:

class Main:
    def thing1(self):
        self.x = 10
    
m = Main()
print(m.x)

This code above will not work, until I call the method, e.g:

class Main:
    def thing1(self):
        self.x = 10
    
m = Main()
m.thing1()
print(m.x)

or

class Main:
    def __init__(self):
        self.thing1()

    def thing1(self):
        self.x = 10
    
m = Main()
print(m.x)

I want to know if there is a way I can check if this instance attribute exists in the method without having to call it.

I have tried using:

  • hasattr()
  • dir()
  • __ dict __

None of them will show that I have a instance attribute called 'x' in thing1

As well as this, I would greatly appreciate it if you could show me how I could check if an instance attribute in a method exists through another method.

class Main:
    def thing1(self):
        self.x = 10
    
    def check(self):
        # Is there a way I can check if 'x' exists in the method names thing1, without having to call it.
    
m = Main()

Thank you for taking the time to read this question, and I hope that you have a great day!

Ali Awan
  • 180
  • 10
  • 2
    Well, you *don't* have an instance attribute until you call the method. Which is why you should create all attributes in `__init__`, so this kind of confusion doesn't exist. Assignment is declaration, the attribute doesn't "exist" before it is being assigned to. Linters will warn when you assign to attributes not created in `__init__` for this reason. – deceze Mar 03 '21 at 08:54
  • 2
    "I have tried using: ``hasattr()`` ``dir()`` ``__ dict __``" Please show how you tried that, since these are exactly the ways to check for attributes. If they do *not* work, you are either using them wrong or are trying to do something that is no obvious from the description. – MisterMiyagi Mar 03 '21 at 08:55
  • Are you asking how to find out which method sets/defines/modifies which attributes? – MisterMiyagi Mar 03 '21 at 08:57

1 Answers1

-1

Indeed hasattr() definitely works. See interactive example below:

>>> class Main:
...     def thing1(self):
...         self.x = 10
... 
>>> m = Main()
>>> hasattr(m, 'x')
False
>>> m.thing1()
>>> hasattr(m, 'x')
True
>>> print(m.x)
10

It's worth noting, though, that attributes should be initialized in the constructor. It's good practice to use __slots__ to declare attributes, but they must still be initialized. Also, class variables (attributes) are initialized outside the constructor. See example below:

class Main:
    c = 5
    __slots__ = ('x', 'y')
    def __init__(self):
        self.y = 12
    def thing1(self):
        self.x = 10

m = Main()
print(hasattr(m, 'x'))
print(hasattr(m, 'y'))
print(m.c)

Output:

False
True
5

After reading the question again and additional comments, it seems that you want to access an attribute that is initalized in a method, without actually calling said method. This is not possible because the attribute won't actually exist until it is initialized.

The only way I can think of to determine if the attribute would exist after the method call, is to read the code of the function in your program and check for the presence of the attribute. This is one crude example, which by no means is guaranteed to always work:

import inspect
lines = inspect.getsource(Main.thing1)
print('self.x' in lines)

The above, would print True for the code in question. I cannot think of a use case where this would be useful and strongly discourage it, but it's good to know the capabilities of Python.

Nagev
  • 10,835
  • 4
  • 58
  • 69
  • Thank you for your reply, I think that there may be a bit of confusion on what I am asking because of how I phrased the question. I know that hasattr() works once I run the method, however I want to check if I can do this without having to run the method(e.g. is there a way in which I can run: hasattr(m, 'x') - and get True back without having to run m.thing1() first) – Ali Awan Mar 03 '21 at 10:00
  • Is your question how to check if an attribute exists, or how to assign an attribute? The only way `hasattr()` returns True is if the attribute exists. The attribute will exist if you initialize it in the constructor (e.g. `__init__(self): self.x = 10`) or assign it later, as in your `thing1()` example. – Nagev Mar 03 '21 at 10:31
  • Ok thank you. I guess that's the only way to do it. – Ali Awan Mar 03 '21 at 10:53
  • I think I get what you meant now and updated the answer. – Nagev Mar 03 '21 at 16:09