Python中对象名出现奇怪错误

2024-04-25 14:37:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在从this web page学习Python(它是中文,请专注于代码)并且我想在windows7上使用python2.7.3来练习代码。但是我发现对象名有一个非常奇怪的错误。代码如下:

class Person:
    '''Represents a person.'''
    population = 0

    def __init__(self, name):
        '''Initializes the person\'s data.'''
        self.name = name
        print '(Initializing %s)' % self.name

        # When this person is created, he/she
        # adds to the population
        Person.population += 1

    def __del__(self):
        '''I am dying.'''
        print '%s says bye.' % self.name

        Person.population -= 1

        if Person.population == 0:
            print 'I am the last one.'
        else:
            print 'There are still %d people left.' % Person.population

    def sayHi(self):
        '''Greeting by the person.
       Really, that\'s all it does.'''
        print 'Hi, my name is %s.' % self.name

    def howMany(self):
        '''Prints the current population.'''
        if Person.population == 1:
            print 'I am the only person here.'
        else:
            print 'We have %d persons here.' % Person.population

David = Person('David')
David.sayHi()
David.howMany()

kalam = Person('Abdul Kalam')
kalam.sayHi()
kalam.howMany()

David.sayHi()
David.howMany()

我在运行这些代码时得到了这个错误报告(最后两行)。但是当我把对象变量'David'替换为'Swaroop'或其他名称时,代码可以正常工作!我不知道这是怎么发生的。在

^{pr2}$

Tags: the代码nameselfdefthisamperson
3条回答

我能找到的唯一解释来自^{} documentation(在警告块中):

Due to the precarious circumstances under which __del__() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when __del__() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the __del__() method may already have been deleted or in the process of being torn down (e.g. the import machinery shutting down).

为了验证这一点,我在__del__方法中添加了print globals()

  • 第一个调用:Person出现在带有适当类对象的全局变量中

    {'kalam': None, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'Person': <class __main__.Person at 0x00000000021D7168>, '__name__': '__main__', 'David': <__main__.Person instance at 0x00000000022B0748>, '__doc__': None}
    
  • 第二个调用:Person仍然出现,但是现在有一个None

    {'kalam': None, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'Person': None, '__name__': None, 'David': None, '__doc__': None}
    

现在,为什么改变变量名David会改变这种行为?

破坏的顺序可能是确定的,但规则没有记录在案:我们处于“实现定义”的领域。在本例中,在我的特定Python解释器中,将David重命名为A确实改变了销毁顺序,Person类对象最后被销毁。在

这本身并不是一个修复,它只是一个奇怪的副作用:您不能合理地依赖销毁命令。在

要显示未调用__del__的示例:

class Referencer(object):
    def __init__(self, name):
        self.name = name

    def __del__(self):
        print("__del__ {}".format(self.name))

foo = Referencer('foo')
bar = Referencer('bar')
baz = Referencer('baz')
foo.x = bar
bar.x = foo

del foo
del bar
del baz

您可能会得到这样的输出:

^{pr2}$

您可以得到(至少在Python2.7中):

__del__ baz

当解释器关闭期间调用__del__()方法时,会出现异常。它不能保证此时任何东西都是可用的,在您的例子中,Person变量似乎已经被销毁了。您应该忽略此问题或停止使用__del__()。在

相关问题 更多 >