0

関数呼び出しで多くの名前付きパラメーターを使用する Python ライブラリを作成しましたが、手動で削除するのではなく、これらの名前付きパラメーターをすべて自動的に削除する方法があるかどうか疑問に思っています (これは非常に面倒な作業です)。 .

たとえば、この関数呼び出しを翻訳することは可能でしょうか?

getClass(lang="Java", body=[
    mainMethod(lang="Java", body=[
        println(lang="Java", toPrint="Hello World")
    ])
])

以下の関数呼び出しに変換します (名前付き引数が省略され、より簡潔になりますか?):

getClass("Java", [
    mainMethod("Java", [
        println("Java", "Hello World!")
    ])
])

これを行うために、可能なアプローチの 1 つは、独自の関数呼び出しを文字列として出力する関数を作成することです。ただし、これを実行する関数を作成することはできないと思います。同様に機能する可能性のある、この問題に対する他のアプローチはありますか?

4

1 に答える 1

5

必要はありません。キーワード引数は引き続き位置指定で渡すことができます。必要に応じて、1 つまたは 1 つも指定できないという追加の利点があります。ただし、指定する必要はまったくありません。

>>> def foo(bar=1, baz=[2,3]):
...     print bar, baz
... 
>>> foo()
1 [2, 3]
>>> foo(baz=4)
1 4
>>> foo(10, 20)
10 20

あなたが提供しているコードを誤解している場合は、お知らせください。スティーブの答えは、あなたが実際に文字列を扱っていることを示しているようですが、あなたの投稿にはそれを示すものは何もありませんでした。

独自の関数呼び出しを出力する関数について言及しました。これにより、関数は、渡したのと同じ引数で関数を呼び出すために入力したものとまったく同じように見える文字列を出力する必要があることを意味していると思います。__name__関数の名前をそのまま入力することも、その属性を使用することもできるため、これは比較的簡単に行うことができます。

>>> def goo(a,b):
...     print "{}({}, {})".format(goo.__name__, a, b)
... 
>>> goo(1,2)
goo(1, 2)
>>> def hoo(*args):
...     print "{}({})".format(hoo.__name__, ', '.join((str(arg) for arg in args)))
... 
>>> 
>>> hoo(2,3,4,5)
hoo(2, 3, 4, 5)

それについて考えると、あなたの例は、この動作を任意の関数に許可する一般的な関数が必要なようです-再帰的に。partialsを使用してそれを実現する方法を次に示します (foo()例がより意味をなすように再定義します)。

>>> from functools import partial
>>> def foo(a, b):                                                              
...     return (a if not isinstance(a, partial) else a()) + (b if not isinstance(b, partial) else b())
... 
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> fun()
15
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> def print_pfunc(pfunc):
...     return "{}({}{}{})".format(pfunc.func.__name__, ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args) if pfunc.args else '', ', ' if pfunc.args and pfunc.keywords else '', ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords) if pfunc.keywords else '')
... 
>>> print print_pfunc(fun)
foo(1, foo(foo(2, 4), foo(3, 5)))

あなたがその非常に長いformat()呼び出しのファンでない場合は、別の書き方があります (私のゴミをデコードするのに時間を費やす必要がないように):

def print_pfunc(pfunc):
    args = ""
    if pfunc.args is not None:
        args = ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args)
    kwargs = ""
    if pfunc.keywords is not None:
        kwargs = ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords)
    return "{}({}{}{})".format(pfunc.func.__name__, args, ', ' if args and kwargs else '', kwargs)

これをコードに適応させるには、関数呼び出しを評価する前にパーシャルに変換するコードを記述する必要があります。この時点から何をしたいかはあなた次第です-引数として渡された関数呼び出しが渡される前に評価されるという事実を回避する賢い方法は考えられません.これはあなたがしようとしていることを妨げるからです.行う。

于 2013-07-23T18:20:34.593 に答える