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
键; 这使得您观察到的行为更加随机,只是多次重新运行您的代码可能会或可能不会触发错误消息。