Class attribute metamorphosis
A short note from the series "You have been warned."
The transition from classical programming languages to Python delivers a lot of surprises.
We read documentation:
Create two objects and check the values of all attributes:
So far, all as expected.
We will try to change vtype: this can be done in two ways, which are essentially just different syntax of the same
And everything is fine again.
Now we will try to do the same through the object attribute.
And here is the first surprise: despite the fact that vtype is an attribute of a class, it suddenly becomes an attribute of an object.
Check:
what if…
And again class attribute.
The following expression no longer passes
And the last example that emulates class overrides and the removal of the vtype attribute.
If you start to deal with namespace-s, then this behavior becomes clear.
However, for programmers who have previously worked with normal languages, this at least seems strange. And if we talk about large projects that are supported by several generations of developers, this may turn out to be a deadline, etc.
Taking into account the concept of Python that everything is open to all, why not access the “cool” attributes only through __class__ or its equivalent. In my opinion, it would somehow protect against surprises and make you think 10 times before assigning something to cool attributes at the object level.
Update: PrintAttr text
The transition from classical programming languages to Python delivers a lot of surprises.
We read documentation:
For example,Let's play
classVessel:#class attribute
vtype = "boat"#instance attributedef__init__(self, name):
self.name = name
# ислючительно для печатиdef__str__(self):
res= '>>'for a in inspect.getmembers( self):
ifnot a[0].startswith("__"): res += f"{a[0]}={a[1]:<14}"for a in inspect.getmembers( self.__class__):
ifnot a[0].startswith("__"): res += f"__class__.{a[0]}={a[1]:<14}"return res
Create two objects and check the values of all attributes:
Iowa = Vessel("Iowa")
Drum=Vessel("Drum")
printAttr(Iowa, Drum)
>>name=Iowa vtype=boat __class__.vtype=boat
>>name=Drum vtype=boat __class__.vtype=boat
So far, all as expected.
We will try to change vtype: this can be done in two ways, which are essentially just different syntax of the same
Vessel.vtype = "USS boat"
printAttr(Iowa, Drum)
>>name=Iowa vtype=USS boat __class__.vtype=USS boat
>>name=Drum vtype=USS boat __class__.vtype=USS boat
Iowa.__class__.vtype = 'USS WW2 Boat'
printAttr(Iowa, Drum)
>>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat
>>name=Drum vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat
And everything is fine again.
Now we will try to do the same through the object attribute.
Drum.vtype = 'submarine'
printAttr(Iowa, Drum)
>>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat
>>name=Drum vtype=submarine __class__.vtype=USS WW2 Boat
And here is the first surprise: despite the fact that vtype is an attribute of a class, it suddenly becomes an attribute of an object.
Check:
Vessel.vtype = "NAVY Museum"
>>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum
>>name=Drum vtype=submarine __class__.vtype=NAVY Museum
what if…
del Drum.vtype
>>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum
>>name=Drum vtype=NAVY Museum __class__.vtype=NAVY Museum
And again class attribute.
The following expression no longer passes
del Drum.vtype
printAttr(Iowa, Drum)
del Drum.vtype
AttributeError: vtype
And the last example that emulates class overrides and the removal of the vtype attribute.
Drum.vtype = 'submarine'del Vessel.vtype
printAttr(Iowa, Drum)
>>name=Iowa
>>name=Drum vtype=submarine
If you start to deal with namespace-s, then this behavior becomes clear.
However, for programmers who have previously worked with normal languages, this at least seems strange. And if we talk about large projects that are supported by several generations of developers, this may turn out to be a deadline, etc.
Taking into account the concept of Python that everything is open to all, why not access the “cool” attributes only through __class__ or its equivalent. In my opinion, it would somehow protect against surprises and make you think 10 times before assigning something to cool attributes at the object level.
Update: PrintAttr text
defprintAttr(*o):for a in o:
print(a)