📜 ⬆️ ⬇️

Class attribute metamorphosis

A short note from the series "You have been warned."

Transition from classical programming languages ​​to Python delivers a lot of surprises.
We read documentation:
For example,
Let's try to play

class Vessel: #class attribute vtype = "boat" #instance attribute def __init__(self, name): self.name = name #    def __str__(self): res= '>>' for a in inspect.getmembers( self): if not a[0].startswith("__"): res += f"{a[0]}={a[1]:<14}" for a in inspect.getmembers( self.__class__): if not 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, everything is as expected.

Let's try to change vtype: this can be done in two ways, which are essentially just a 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 again, everything is in order.

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 be a deadline, etc.

Taking into account the concept of Python, that everything is open to all, why not make access to 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

 def printAttr(*o): for a in o: print(a) 

Source: https://habr.com/ru/post/427065/


All Articles