Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between accessing an instance attribute and a class attribute

I have a Python class

class pytest:
    i = 34
    def func(self):
        return "hello world"

When I access pytest.i, I get 34. I can also do this another way:

a = pytest()
a.i

This gives 34 as well.

If I try to access the (non-existing) pytest.j, I get

Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
pytest.j
AttributeError: class pytest has no attribute 'j'

while when I try a.j, the error is

Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
a.j
AttributeError: pytest instance has no attribute 'j'

So my question is: What exactly happens in the two cases and what is the difference?

like image 295
Nazmul Hasan Avatar asked May 18 '26 11:05

Nazmul Hasan


1 Answers

No, these are two different things.

In Python, everything is an object. Classes are objects, functions are objects and instances are objects. Since everything is an object, everything behaves in a similar way. In your case, you create a class instance (== an object with the type "Class") with the name "pytest". That object has two attributes: i and fuc. i is an instance of "Integer" or "Number", fuc is an instance of "Function".

When you use "pytest.j", you tell python "look up the object pytest and when you have it, look up i". "pytest" is a class instance but that doesn't matter.

When you create an instance of "pytest" (== an object with the type "pytest"), then you have an object which has "defaults". In your case, a is an instance of pytest which means that anything that can't be found in a will be searched in pytest, next.

So a.j means: "Look in a. When it's not there, also look in pytest". But j doesn't exist and Python now has to give you a meaningful error message. It could say "class pytest has no attribute 'j'". This would be correct but meaningless: You would have to figure out yourself that you tried to access j via a. It would be confusing. Guido won't have that.

Therefore, python uses a different error message. Since it does not always have the name of the instance (a), the designers decided to use the type instead, so you get "pytest instance...".

like image 85
Aaron Digulla Avatar answered May 20 '26 00:05

Aaron Digulla