这段代码...
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')
我看到的唯一区别是最后一个变量名是“vb”与“v”。
我正在学习 Python,现在正在研究 OOP。
最佳答案
是的,虽然不是直接导致这种情况的变量名那么多。
当 Python 退出时,所有模块也会被删除。清理模块的方法是将模块中的所有全局变量设置为 None
(因此这些引用不再引用原始对象)。这些全局变量是字典对象中的键,由于字典是任意排序的,重命名一个变量可以改变变量被清除的顺序。
当您重命名 v
时至vb
,您更改了清除变量的顺序,现在 Person
最后清除。
一种解决方法是使用 type(self).num_of_people -= 1
在 __del__
替代方法:
def __del__(self):
type(self).num_of_people -= 1
因为实例仍然会一直引用类,或者测试是否Person
未设置为 None
:
def __del__(self):
if Person is not None:
Person.num_of_people -= 1
两个音符:
CPython 3.4 不再将全局变量设置为
None
(在大多数情况下),根据 Safe Object Finalization ;见 PEP 442 .CPython 3.3 自动应用 randomized hash salt到
str
globals
中使用的键字典;这使您观察到的行为更加随机,只需多次重新运行代码可能会也可能不会触发错误消息。
关于python - Python3 变量名称的简单区别能否改变代码的运行方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22864764/