15

を使用しているPythonアプリケーションThreadingTCPServerとのカスタムサブクラスを実装していますBaseRequestHandler。これに伴う問題は、がThreadingTCPServer自動的にスレッドを生成し、ハンドラーのインスタンスを作成して、それらのhandle()関数を呼び出すように見えることです。ただし、これでは、グローバル変数またはクラス変数を使用する以外にデータをハンドラーに渡す方法がありません。どちらもハックのようです。それを行うためのより良い方法はありますか?

理想的には、これは次のようになります。

class ThreadedTCPServer(ThreadingTCPServer):
    def process_request(self, *args, **kwargs):
        ThreadingTCPServer.process_request(self, data, *args, **kwargs)

のようなハンドラーで

class ThreadedTCPRequestHandler(BaseRequestHandler):
    def handle(self,data):
        #do something with data
4

3 に答える 3

28

私はまったく同じことに出くわしました。私の解決策は次のとおりです。

class ThreadedTCPRequestHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        print(self.server.mycustomdata)

class ThreadedTCPServer(SocketServer.ThreadingTCPServer):
    pass

server = ThreadedTCPServer((args.host, args.port), ThreadedTCPRequestHandler)
server.mycustomdata = 'foo.bar.z'
server.serve_forever()

RequestHandlerは、サーバーオブジェクトを3番目のパラメーターとして使用して呼び出され、self.server属性として保存されるため、アクセスできます。この属性を呼び出し可能に設定すると、簡単に呼び出すこともできます。

def handle(self):
    mycustomdata = self.server.mycustomdata()
于 2013-11-08T23:10:33.613 に答える
5

__init__最初の答えは私にとってはうまくいきましたが、メソッドを変更してコンストラクターに属性を渡す方がクリーンだと思います。

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):

    def __init__(self, host_port_tuple, streamhandler, Controllers):
        super().__init__(host_port_tuple, streamhandler)
        self.Controllers = Controllers

コンストラクターの3番目のパラメーター'Controllers'に注意してください。次に、そのパラメーターなしでsuperを呼び出し、新しい属性Controllersをプロパティself.Controllersに設定します。クラスの残りの部分は変更されていません。次に、Requesthandlerで、上記のように「server」属性を使用してパラメーターにアクセスします。

def handle(self):        
    self.Controllers = self.server.Controllers
    <rest of your code>

上記の答えとほとんど同じですが、コンストラクターがオーバーロードされており、コンストラクターに必要な属性を追加するだけなので、少しわかりやすくなっています。

server = ServerInterface.ThreadedTCPServer((HOST, PORT), ServerInterface.ThreadedTCPRequestHandler, Controllers)
于 2016-02-12T14:23:38.297 に答える
2

handleはサブクラスによって実装されるためBaseRequest、呼び出し元に渡されることなく、それ自体からデータを取得できます。(handleラムダなど、リクエストインスタンスの呼び出し可能な属性である可能性もありますuser_data。通常、慣用的に設計されたPythonでは明示的な引数は不要です。)

SocketServerコードを見ると、使用するインスタンスに追加データを格納するサブタイプコンストラクターにfinish_request追加データを渡すためにオーバーライドするのは簡単です。BaseRequestHandlerhandle

于 2012-09-02T14:03:42.950 に答える