Reputation: 849
I've seen examples of how I can make a static variable in a class. Here is an example:
class A:
_i = 0
@property
def i(self):
print(type(self)) # <class '__main__.A'>
return type(self)._i
@i.setter
def i(self, val):
type(self)._i = val
type(self)
work and make these variables static? < class '__main__.A' >
mean in OOP and polymorphism?Upvotes: 1
Views: 94
Reputation: 365707
How type(self) works
It just returns the type of self
. You can call type
on any object to get its type:
>>> type(2)
int
>>> class C(object): pass
>>> type(C)
type
>>> c = C()
>>> type(c)
__main__.C
(The output may look slightly different on Python 2 vs. Python 3, or on different Python implementations.)
… and make that variables are static?
Well, first, these aren't static variables, they're class variables. If you don't have any inheritance, there's no difference—but if you do… I'll come back to that.
If you create an instance:
>>> a = A()
… and assign a value to i
:
>>> a.i = 3
… it calls the setter for the i
property, passing a
as the self
parameter—just like a normal method call.
So, since self
is a
, and type(a)
is A
, then type(self)
is also A
.
Which means type(self)._i
is A._i
. In other words, it's the class attribute.
So, why is this a class attribute rather than a static attribute? Well, let's add a subclass:
>>> a = A()
>>> class B(A):
... _i = 1
>>> b = B()
>>> b.i = 5
>>> A._i
0
>>> B._i
5
Each subclass can have its own _i
. And because the setter is setting type(self)._i
, when self
is b
, so type(self)
is B
, type(self)._i
is B._i
, not A._i
.
What does it
< class '__main__.A' >
mean in OOP and polymorphism
In Python, everything has a repr
, meant for programmers, that gets printed out when you evaluate it at the interactive prompt. It's also used as the str
(the thing that gets printed by print
) if there's nothing better to use as a human-readable (as in real humans, not us programmers) representation.
In general, a repr
is either:
<>
that includes the type, some kind of identifying information if there is any, and some way to distinguish the object from other instances, otherwise.For types, what you get inside the angle brackets is the fact that it's a class (that's the class
part), and the qualified name (that's the __main__.A
part, telling you that it's a class named A
defined at the top level of a module named __main__
), which is both the useful identifier and the way to distinguish it from other classes.
What does is mean specifically in OOP and polymorphism? I can't think of a good answer to that. Even if Python didn't support polymorphism, even if it didn't have first-class types, __main__.A
and __main__.B
would still be different objects worthy of distinct names, right?
And if you're wondering what kind of name __main__
is: that's just the name of the special module used to run your top-level script or your interactive interpreter session. If you've ever seen a if __name__ == '__main__':
guard, that's exactly what it's testing.
Upvotes: 4
Reputation: 522085
type()
returns the class
that an instance was constructed from. I.e. if you do foo = A()
(create a new instance of A
and assign it to foo
), then type(foo)
returns A
again. That's what <class '__main__.A'>
is, it tells you it's the A
class
object.
Now all you're doing with type(self)._i
is the same as A._i
. That _i
is an attribute of the class
A
object, which only exists once. Et voilà, that's all that "static" attributes are.
Upvotes: 1