Pythonドキュメント がThread.run()
の場合:
サブクラスでこのメソッドをオーバーライドできます。標準のrun()メソッドは、ターゲット引数としてオブジェクトのコンストラクターに渡された呼び出し可能オブジェクトを呼び出します。引数がある場合は、それぞれargs引数とkwargs引数から引数を取得します。
次のコードを作成しました。
class DestinationThread(threading.Thread):
def run(self, name, config):
print 'In thread'
thread = DestinationThread(args = (destination_name, destination_config))
thread.start()
しかし、それを実行すると、次のエラーが表示されます。
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner
self.run()
TypeError: run() takes exactly 3 arguments (1 given)
私は明らかな何かを見逃しているようですが、私が見たさまざまな例はこの方法論で動作します。最終的には、コンストラクタが正しい方法ではない場合、文字列と辞書をスレッドに渡すだけで、スレッドを開始する前に値を設定する新しい関数を作成しようとしています。
これを最善に達成するための提案はありますか?
スレッドをサブクラス化する必要はありません。 APIがこれをサポートする唯一の理由は、Javaから来た人がそれを気楽に行う唯一の方法である場合、より快適にするためです。
使用することをお勧めするパターンは、メソッドをThreadコンストラクターに渡し、単に.start()
を呼び出すことです。
def myfunc(arg1, arg2):
print 'In thread'
print 'args are', arg1, arg2
thread = Thread(target=myfunc, args=(destination_name, destination_config))
thread.start()
以下は、__init__
を拡張せずに、スレッドを使用して引数を渡す例です。
import threading
class Example(threading.Thread):
def run(self):
print '%s from %s' % (self._Thread__kwargs['example'],
self.name)
example = Example(kwargs={'example': 'Hello World'})
example.start()
example.join()
そして、ここにマルチプロセッシングを使用した例があります:
import multiprocessing
class Example(multiprocessing.Process):
def run(self):
print '%s from %s' % (self._kwargs['example'],
self.name)
example = Example(kwargs={'example': 'Hello World'})
example.start()
example.join()
_threading.Thread
_のドキュメントは、未使用の位置引数およびキーワード引数が実行に渡されることを暗示しているように見える場合があります。ではない。
余分な位置引数とキーワードkwargs
は、デフォルトの_threading.Thread.__init__
_メソッドによって実際にトラップされますが、_target=
_キーワードを使用して指定されたメソッドにのみ渡されます。それらはrun()
メソッドに渡されません。
実際、 Threading documentation atは、それがisを呼び出すデフォルトのrun()
メソッドであることを明確にしますトラップされた引数とkwargs
を備えた提供された_target=
_メソッド:
「サブクラスでこのメソッドをオーバーライドできます。標準のrun()メソッドは、オブジェクトのコンストラクターにターゲット引数として渡された呼び出し可能なオブジェクトを呼び出します(存在する場合)。
オーバーライドされたrun()
メソッドが追加の引数を取るかどうかに関する混乱のいくつかに対処するために、threading.Thread
から継承されたメソッドが行うことを行うオーバーライドされたrun()
メソッドの実装があります。
これは、単にrun()
;をオーバーライドする方法を確認するためのものです。意味のある例ではありません。必要なのが、順次引数やキーワード引数を使用してターゲット関数を呼び出すことだけである場合、サブクラスを持つ必要はありません。これが指摘されていますin Jerub's answer この質問に対する。
次のコードは、Python v2とv3の両方をサポートしています。
特にPython 2コードのマングルされた属性名へのアクセスは見苦しいですが、これらの属性にアクセスする別の方法を知りません(知っていれば教えてください...):
import sys
import threading
class DestinationThread(threading.Thread):
def run(self):
if sys.version_info[0] == 2:
self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
else: # assuming v3
self._target(*self._args, **self._kwargs)
def func(a, k):
print("func(): a=%s, k=%s" % (a, k))
thread = DestinationThread(target=func, args=(1,), kwargs={"k": 2})
thread.start()
thread.join()
表示されます(Windows 7ではPython 2.6、2.7、3.4でテスト済み):
func(): a=1, k=2
Threadコンストラクターの引数ターゲットは呼び出し可能オブジェクトなので、__call__
runメソッドとして
class Worker(object):
def __call__(self, name, age):
print('name, age : ',name,age)
if __== '__main__':
thread = Thread(target=Worker(), args=('bob','50'))
thread.start()
出力:
('name, age : ', 'bob', '50')
Runメソッドは3つの引数を受け入れるように定義しますが、1つの引数で呼び出します(Pythonはオブジェクトへの参照で呼び出します)。
__init__
の代わりに実行する引数を渡す必要があります。
または、__init__
メソッドが代わりに引数を受け入れるようにします。