2

在对 Python 2.7.3 的线程模块的线程进行子类化时,我遇到了奇怪的行为。考虑下一个名为 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 文档声明它是允许的,我不明白为什么覆盖不起作用。

谢谢!

4

1 回答 1

3

您遇到的事情在 Python中称为名称修饰。

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

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

self._Thread__target

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

于 2012-08-20T10:23:35.183 回答