类属性变形

系列“您被警告”中的简短说明。

从经典的编程语言到Python的转换带来了很多惊喜。
阅读文档:
一般来说,实例变量用于每个实例唯一的数据,类变量用于类的所有实例共享的属性和方法
让我们尝试玩

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 


创建两个对象,检查所有属性的值:

 Iowa = Vessel("Iowa") Drum=Vessel("Drum") printAttr(Iowa, Drum) >>name=Iowa vtype=boat __class__.vtype=boat >>name=Drum vtype=boat __class__.vtype=boat 

到目前为止,符合预期。

让我们尝试更改vtype:这可以通过两种方式完成,它们实质上只是相同语法的不同

 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 

再说一次,一切都井井有条。

现在,让我们尝试通过对象的属性执行相同的操作。

 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 

这是第一个惊喜:尽管vtype是类的属性,但突然它变成了对象的属性。

检查:

 Vessel.vtype = "NAVY Museum" >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=submarine __class__.vtype=NAVY Museum 

如果...

  del Drum.vtype >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=NAVY Museum __class__.vtype=NAVY Museum 

再次是class属性。

以下表达式不再通过

 del Drum.vtype printAttr(Iowa, Drum) del Drum.vtype AttributeError: vtype 

最后一个模拟类的示例将覆盖并删除vtype属性。

 Drum.vtype = 'submarine' del Vessel.vtype printAttr(Iowa, Drum) >>name=Iowa >>name=Drum vtype=submarine 

如果您开始处理名称空间,那么这种行为就变得可以理解。
但是,对于以前使用普通语言的程序员来说,这至少看起来很奇怪。 而且,如果我们谈论的是由几代开发人员支持的大型项目,那可能是截止日期等的失败。

考虑到Python的概念,即一切都向所有人开放,为什么不仅通过__class__或其类似物访问“ cool”属性。 我认为,这至少可以防止意外,并让我思考10次,然后再在对象级别为类属性分配某些东西。

更新:文本PrintAttr

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

Source: https://habr.com/ru/post/zh-CN427065/


All Articles