92

fetch_dataリモート API にアクセスしてヒットし、データを取得して、応答オブジェクトにラップして返すPython 関数があります。以下のように見えます。

def fetch_data(self, foo, bar, baz, **kwargs):
    response = Response()
    # Do various things, get some data
    return response

ここで、応答データが「さらにデータがあります。より多くのデータを取得するには、インクリメントされたpageパラメーターを使用して電話してください」と言う可能性があります。したがって、基本的に「メソッド呼び出し」(関数、パラメーター) を応答オブジェクトに格納したいのでResponse.get_more()、格納された関数とパラメーターを調べて、(ほぼ) 同じ方法で関数を再度呼び出すことができます。パラメータ、新しい値を返すResponse

に保存できるようfetch_dataに定義されている場合。ただし、、 、およびを心配する必要があります。保存することはできますが、それは非常に望ましくない量の繰り返しです。fetch_data(*args, **kwargs)(fetch_data, args, kwargs)responseselffoobarbaz(fetch_data, foo, bar, baz, kwargs)

基本的に、関数内から、関数の名前付きパラメーターを含め、完全に入力された*argsand を取得する方法を考え出そうとしています。**kwargs

4

8 に答える 8

134

基本的に、関数内から、関数の名前付きパラメーターを含め、完全に設定された *args と **kwargs を取得する方法を考え出そうとしています。

locals()関数の先頭で引数を保存するのはどうですか?

def my_func(a, *args, **kwargs):
    saved_args = locals()
    print("saved_args is", saved_args)
    local_var = 10
    print("saved_args is", saved_args)
    print("But locals() is now", locals())

my_func(20, 30, 40, 50, kwarg1='spam', kwarg2='eggs')

次の出力が得られます。

saved_args is {'a': 20, 'args': (30, 40, 50), 'kwargs': {'kwarg1': u'spam', 'kwarg2': u'eggs'}}
saved_args is {'a': 20, 'args': (30, 40, 50), 'kwargs': {'kwarg1': u'spam', 'kwarg2': u'eggs'}}
But locals is now {'a': 20, 'saved_args': {...}, 'args': (30, 40, 50), 'local_var': 10, 'kwargs': {'kwarg1': u'spam', 'kwarg2': u'eggs'}}

帽子のヒント: https://stackoverflow.com/a/3137022/2829764

于 2014-06-01T18:18:16.380 に答える
42

私がすることではありませんがinspect.signature、メソッドが取る引数をイントロスペクトするために使用できます。

>>> import inspect
>>> def foobar(foo, bar, baz):
...     return inspect.signature(foobar)
... 
>>> foobar(1, 2, 3)
<Signature (foo, bar, baz)>

返されたSignatureインスタンスには、引数値のリストを生成するためにと一緒に使用できる、順序付けられたパラメーター (.parameters属性)のコレクションがあります。locals()

>>> def foobar(foo, bar, baz):
...     sig, foobar_locals = inspect.signature(foobar), locals()
...     return [foobar_locals[param.name] for param in sig.parameters.values()]
...
>>> foobar(1, 2, 3)
[1, 2, 3]

ただし、高度な関数デコレータなどを行う場合にのみ、そのような魔法が必要です。ここはやり過ぎだと思います。

于 2012-05-23T17:01:19.327 に答える
15

より Pythonic な方法はyield、サーバーが何かを返し続ける限り、関数をジェネレーターに変換し、データをフェッチして ing することだと思います。

これにより、きちんとしたコードが得られ、反復間で引数を保持するという複雑さをすべて回避できるようになります (Python が魔法のように実行してくれます :-))

于 2012-05-23T16:59:35.567 に答える
11

inspect.getargspecバージョン 3.0 から廃止されました。呼び出し可能オブジェクトのためのより優れたイントロスペクト API を提供するUsesignature()および Signature Object。

>>> from inspect import signature
>>> def foo(a, *, b:int, **kwargs):
...     pass

>>> sig = signature(foo)

>>> str(sig)
'(a, *, b:int, **kwargs)'

>>> str(sig.parameters['b'])
'b:int'

>>> sig.parameters['b'].annotation
<class 'int'>
于 2016-09-15T18:12:45.633 に答える
1

kwargs はキーとして 'foo'、'bar'、または 'bad' を持たないため、これらのエントリ (およびその値) を kwargs に追加し、(fetch_data、kwargs) だけを保存できます。

于 2012-05-23T17:00:27.443 に答える