Reputation: 29
x = 5
class A:
x += 1 # here we can access and change the value of x in class but only for class
print(f"x from inside class is {x}")
print(x)
why print inside the class although i not make instance from the class A
Upvotes: 2
Views: 64
Reputation: 114320
Python code is executed top to bottom. The statement class A
triggers the creation of a new class object, which will be finalized and assigned to the global name A
when the unindent is reached.
A class is created by running all the statements in the class body in a separate isolated namespace. Once the class body finishes executing, the namespace is wrapped up into a class object. The result can be pre-processed by a metaclass, but that's about it.
The statement x += 1
is roughly equivalent to x = x.__iadd__(1)
. The augmented assignment happens inside the class namespace. It does not affect the global name x
because assignments happen in the class namespace and integers are immutable. The immutability is important, because the x
on the right hand side of that assignment is from the global namespace, even if the left one is not.
A mutable object like a list would work differently. If x
was a list, x += [1]
would reassign the result of x.__iadd__([1])
to a class variable x
, just as for the integer case. However, the operation __iadd__
modifies a list object in-place. That means that both global x
and A.x
would refer to the same expanded list.
A class
statement, like a def
statement is an assignment operation. You are telling the interpreter to run a code snippet that initializes your class. This is different from def
, which does not run any lines of code that you wrote, instead compiling them into a function object.
You see the printout happen as the interpreter creates the class namespace. The class ends up with a variable called x
set to 6
. If you had def
statements, there would also be functions in the class namespace. If you attempted to access those functions through an instance of the class, they would get bound as methods since function objects are non-data descriptors.
Upvotes: 1
Reputation: 2110
The variable x
initialized outside is pointing to different object address from that of variable x
inside the class. It creates a new static variable for class A with the value of outside x+1
. To see this, I am printing the address pointed by variables here. See that the addresses pointed by variable x
are different outside and inside the class.
x= 5
print('address of x just after outside initialization',id(x))
class A:
x += 1 # here we can access and change the value of x in class but only for class
print(f"x from inside class is {x}")
print('address of x from inside class is', id(x))
print('value outside class',x)
print('address of x just after execution',id(x))
Output:
address of x just after outside initialization 94841399200384
x from inside class is 6
address of x from inside class is 94841399200416
5
address of x just after execution 94841399200384
Upvotes: 1
Reputation: 21275
This code is equivalent to yours.
x = 5
class A:
x = x + 1
print(f"x from inside class is {x}")
print(x)
print(A.x)
And it outputs:
x from inside class is 6
5
6
So as you can see, what you have done with x += 1
is define a class variable A.x
that has the value of x + 1
. This x
is pulled from the outer scope (value = 5). So you actually have 2 variables at play here, not one like you are assuming.
Upvotes: 0
Reputation: 5242
You have created a static variable x, one that is not tied to any instance of A and is created immediately. To create an instance variable, do this:
class A:
def __init__(self):
self.x = 1
Upvotes: 0