使用**kwargsとSimpleXMLRPCServer python
-
02-07-2019 - |
質問
しているクラスでいくとして、リモートサービス用のジャケットSimpleXMLRPCServer.サーバの起動は以下のようなものです:
server = SimpleXMLRPCServer((serverSettings.LISTEN_IP,serverSettings.LISTEN_PORT))
service = Service()
server.register_instance(service)
server.serve_forever()
そしていServiceRemoteクラスは以下のようなものです:
def __init__(self,ip,port):
self.rpcClient = xmlrpclib.Server('http://%s:%d' %(ip,port))
def __getattr__(self, name):
# forward all calls to the rpc client
return getattr(self.rpcClient, name)
すべてのServiceRemoteオブジェクトに転送することxmlrpclib.サーバは、その前にリモートサーバーです。問題は、方法、サービスと名前の変数引数:
@useDb
def select(self, db, fields, **kwargs):
pass
に@useDbデコレータをラッピングした機能をdbの前に、それを開放していくことが、その閉じた後の前を返します。
私がこのメソッドを呼び出しにエラー"電話()たなキーワード引数の名前"".でも利用は可能で呼び出方法を変数名引数が遠隔か?やまをオーバーライドの各メソッド変動します。
感謝に対応。私は、コードは多少前後で問題はなくなります。しかし今から将来の参考にすれば確かにうまく管理できなければならない行の位置引数は、リモート呼び出し.と思い組み合わせのトーマスpraptaks近づいているものがいいでしょう。旋kwargsに位置引数がクライアントを通じてxmlrpclient、ラッパー方法serversideドの位置引数になります。
解決
できないことがあり、平野xmlrpcのではないという概念のキーワード引数になります。ただし、重ね合わせてプロトコルのxmlrpcうすでにご存じの通りリストとして最初の引数辞書として第二に、その適切な支援のコードでこの透明になり、ご利用の例は以下:
サーバー
from SimpleXMLRPCServer import SimpleXMLRPCServer
class Server(object):
def __init__(self, hostport):
self.server = SimpleXMLRPCServer(hostport)
def register_function(self, function, name=None):
def _function(args, kwargs):
return function(*args, **kwargs)
_function.__name__ = function.__name__
self.server.register_function(_function, name)
def serve_forever(self):
self.server.serve_forever()
#example usage
server = Server(('localhost', 8000))
def test(arg1, arg2):
print 'arg1: %s arg2: %s' % (arg1, arg2)
return 0
server.register_function(test)
server.serve_forever()
お客様
import xmlrpclib
class ServerProxy(object):
def __init__(self, url):
self._xmlrpc_server_proxy = xmlrpclib.ServerProxy(url)
def __getattr__(self, name):
call_proxy = getattr(self._xmlrpc_server_proxy, name)
def _call(*args, **kwargs):
return call_proxy(args, kwargs)
return _call
#example usage
server = ServerProxy('http://localhost:8000')
server.test(1, 2)
server.test(arg2=2, arg1=1)
server.test(1, arg2=2)
server.test(*[1,2])
server.test(**{'arg1':1, 'arg2':2})
他のヒント
XML-RPCまだまだコンセプトの'キーワード引数でxmlrpclib試みない支援します。する必要がありコンベンション変更しxmlrpclib._Method受け入れのキーワード引数をとらを用いること。
例えば、私は使用されているXML-RPCサーバに渡されたキーワード引数として二つの引数で'-キーワード'の後の実際の引数は、平一覧です。私は、アクセスできなくなり、コードを書いたアクセスするXML-RPCサーバーからPythonでシンプルなものになっていることはわかってい線:
import xmlrpclib
_orig_Method = xmlrpclib._Method
class KeywordArgMethod(_orig_Method):
def __call__(self, *args, **kwargs):
if args and kwargs:
raise TypeError, "Can't pass both positional and keyword args"
args = list(args)
for key in kwargs:
args.append('-%s' % key.upper())
args.append(kwargs[key])
return _orig_Method.__call__(self, *args)
xmlrpclib._Method = KeywordArgMethod
このmonkeypatchingのための最も簡単な方法なので、一部の無骨のモジュールのグローバル変数名-難号化した属性(__請求のためのインスタンス)のServerProxyクラスです。
私がよく知られているようにするプロトコルをサポートしていない名前の変数引数(または名前(<%=args%>等:argsい).に対処すラッパーの**kwargsで、通常の辞書の方法にしたい金がかかる場合があります。このようになっ
サーバ側:
def select_wrapper(self, db, fields, kwargs):
"""accepts an ordinary dict which can pass through xmlrpc"""
return select(self,db,fields, **kwargs)
クライアント側:
def select(self, db, fields, **kwargs):
"""you can call it with keyword arguments and they will be packed into a dict"""
return self.rpcClient.select_wrapper(self,db,fields,kwargs)
免責事項:このコードの概念があって、やればできるんで少しクリーナー(例えば書きデコレータだけです。
してトーマスWoutersと、XML-RPCないキーワード引数になります。での大きな事項の引数としてプロトコルに関しまうというものXML:arg0,arg1,arg2は完全に細は、チーズ、お菓子やベーコンの引数になります。
そう考えをご利用のプロトコル?用のようなドキュメント/リテラルソープにもより回避策などのその他の回答をこちらです。もちろん、このあたりを実現します。
上記のアドバイス、作成したあのコードです。
サーバーラッパー法:
def unwrap_kwargs(func):
def wrapper(*args, **kwargs):
print args
if args and isinstance(args[-1], list) and len(args[-1]) == 2 and "kwargs" == args[-1][0]:
func(*args[:-1], **args[-1][1])
else:
func(*args, **kwargs)
return wrapper
シンクライアント(いま):
_orig_Method = xmlrpclib._Method
class KeywordArgMethod(_orig_Method):
def __call__(self, *args, **kwargs):
args = list(args)
if kwargs:
args.append(("kwargs", kwargs))
return _orig_Method.__call__(self, *args)
xmlrpclib._Method = KeywordArgMethod
で、この対応方法と固定の位置、キーワード引数になります。