Python3variables名称的简单区别可以改变代码的运行方式吗?

这个代码…

class Person: num_of_people = 0 def __init__(self, name): self.name = name Person.num_of_people += 1 def __del__(self): Person.num_of_people -= 1 def __str__(self): return 'Hello, my name is ' + self.name cb = Person('Corey') kb = Person('Katie') v = Person('Val') 

产生以下错误…

 Exception AttributeError: "'NoneType' object has no attribute 'num_of_people'" in <bound method Person.__del__ of <__main__.Person object at 0x7f5593632590>> ignored 

但是这个代码没有。

 class Person: num_of_people = 0 def __init__(self, name): self.name = name Person.num_of_people += 1 def __del__(self): Person.num_of_people -= 1 def __str__(self): return 'Hello, my name is ' + self.name cb = Person('Corey') kb = Person('Katie') vb = Person('Val') 

我看到的唯一区别是最后一个variables名是“vb”与“v”。

我正在学习Python,现在正在开发面向对象的东西。

是的,虽然不是那么多引起这个variables的variables名,但不是直接的。

当Python退出时,所有模块也被删除。 模块清理的方式是将模块中的所有全局variables设置为None (因此这些引用不再引用原始对象)。 这些全局variables是字典对象中的键,并且随着字典被任意sorting,重命名一个variables可以改变variables被清除的顺序。

当你把v重命名为vb ,你改变了variables被清除的顺序,现在Person被最后清除。

一种解决方法是在type(self).num_of_people -= 1方法中使用type(self).num_of_people -= 1来代替:

 def __del__(self): type(self).num_of_people -= 1 

因为实例将始终有对类的引用,或者testingPerson是否未设置为None

 def __del__(self): if Person is not None: Person.num_of_people -= 1 

两个注释:

  • 根据安全对象定稿 ,CPython 3.4不再将全局variables设置为None (大多数情况下); 见PEP 442 。

  • CPython 3.3自动将一个随机哈希盐应用到globals字典中使用的str键; 这使得您观察到的行为更加随机,只是多次重新运行您的代码可能会或可能不会触发错误消息。