2

Python 2.7.3のthreading-moduleの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のドキュメントに上書きが許可されていると記載されていることを考えると、上書きが機能しない理由がわかりません。

ありがとう!

4

1 に答える 1

3

あなたが遭遇したことは、Pythonでは名前マングリングと呼ばれています。

これは、二重アンダースコアで始まるすべての非システム属性( "__attrname__"などの属性)が、インタープリターによって_Classname__attrnameとして自動的に名前が変更されることを意味します。これは一種の保護メカニズムであり、このような設計は通常、これらのフィールドに触れないことを意味し(すでに適切な方法で処理されています)、通常は「プライベートフィールド」と呼ばれます。

したがって、何らかの理由でこれらのフィールドにアクセスしたい場合は、上記の表記を使用してください。

self._Thread__target

この属性はクラスで定義されているため、フィールドは_Threadでなく、で始まることに注意してください。_SpecificThreadThread

于 2012-08-20T10:23:35.183 に答える