Python:子类化线程的run方法会产生错误

时间:2012-08-20 10:16:13

标签: python multithreading

当我继承Python 2.7.3的线程模块的Thread时,我遇到了奇怪的行为。 考虑下一个名为test.py的代码:

import threading

def target_function(): print 'Everything OK'

class SpecificThread(threading.Thread):
    def run(self):
        try:
            if self.__target:
                self.__target(*self.__args, **self.__kwargs)
        finally:
            # Avoid a refcycle if the thread is running a function with
            # an argument that has a member that points to the thread.
            del self.__target, self.__args, self.__kwargs  

def check():
    thread = SpecificThread(target=target_function)
    #thread = threading.Thread(target=target_function)
    thread.run()
    print thread.name, 'is running:', thread.is_alive()

运行check()时,此代码会引发以下错误:

>>> check()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 18, in check
    thread.run()
  File "test.py", line 13, in run
    del self.__target, self.__args, self.__kwargs  
AttributeError: _SpecificThread__target

虽然,SpecificThread的run()方法与原始threading.py模块中的代码完全相同。 如果使用threading.Thread或者当SpecificThread不覆盖run()方法时,脚本运行完美无缺。我不明白为什么覆盖不起作用,考虑到Python文档声明它是允许的。

谢谢!

1 个答案:

答案 0 :(得分:3)

您遇到的事情在Python中称为name mangling

这意味着所有以双下划线开头的非系统属性(如“__attrname__”)都会被解释器自动重命名为_Classname__attrname)。这是一种保护机制,这种设计通常意味着你甚至不能触摸那些领域(它们已经以适当的方式处理),通常被称为“私人领域”。

因此,如果您出于某种原因想要访问这些字段,请使用上面的符号:

self._Thread__target

请注意,该字段以_Thread开头,而不是_SpecificThread,因为此属性是在Thread类中定义的。