0

件名はかなりばかげているように聞こえるので、いくつかのコードを示します。

def foo(**kwargs):
    # How can you detect the difference between (**{}) and ()?
    pass
foo(**{})
foo()

fooの内部を検出する方法はありますか、メソッドはどのように呼び出されましたか?

アップデート1

なぜあなたが何かをしたいのかというコメントがいくつかあったので、いくつかの背景を説明しようと思います。

super(MyClass, self).foo(*args, **kwargs)吸う-多くの無駄な複製。'self.super()'を書きたい。この場合、スーパークラスを呼び出して、呼び出し元のメソッドが取得したすべてのパラメーターも渡します。チャームのように機能します。

今問題のある魔法の部分:

'self.super(something)'と言いたいのですが、この場合、'something'だけがsuperメソッドに渡されます。ほとんどの場合に機能します。

これはそれが壊れるところです:

def foo(self, fnord=42, *args, **kwargs):
    self.super(*args, **kwargs)

*argsしたがって、スーパーメソッドは、呼び出し元のメソッド**kwargsが空であるという引数を取得する必要があります。ただし、現在、ライブラリはこの条件を検出できず、「fnord」を含むすべての引数を渡します。

もちろんself.super.foo(*args, **kwargs)、代替構文として使用することもできますが、それは不十分です:-)

PS:はい、私はp3kのスーパーを知っていますが、それでも良くなく、Python2.xでは動作しません...

アップデート2

実際、Pythonのastモジュールでさえ**{}ast.parse('foo(**{})'))を削除しているため、これは解析プロセスの非常に早い段階で発生するため、後でこの情報を取得することはできません...

したがって、最終的には、その特定の問題をあきらめるか(AmbiguousSyntaxErrorを発生させる)、〜unutbuによって提案されたテキスト解析を使用する必要があります。私のアプローチを再考すると、後者は実際に実行可能かもしれません。なぜなら、それがself.super(\s*)、であるかどうかを知る必要があるだけだからself.super(\S+)です。

4

3 に答える 3

0

このハックはCPythonでのみ機能します。

import traceback

def foo(**kwargs):
    # stack is a list of 4-tuples: (filename, line number, function name, text)
    # see http://docs.python.org/library/traceback.html#module-traceback

    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    print('foo was called: %s'%text)

foo(**{})
# foo was called: foo(**{})
foo()
# foo was called: foo()

これがどのように役立つかの一例として:

def pv(var):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    print('%s: %s'%(text[text.find('(')+1:-1],var))

x=5
pv(x)
# x: 5

pvは値だけで呼び出されますxが、変数の「名前」(呼び出されたとき)と変数の値の両方が出力されることに注意してください。時々私はデバッグ時にこれを使用し、完全な印刷ステートメントを書き出すのが面倒です。

于 2010-03-27T13:56:28.010 に答える
0

基本的に、提供されている Python モジュールでそれを行うことはできません。要件が単純であることを考えると、私にとってはかなりうまく機能するプレーンテキストの正規表現にフォールバックする必要がありました。

于 2010-04-17T10:24:09.983 に答える
0

あなたが書いた元の質問への更新では、次のようなことができるようにしたいと考えています。

def foo(self, fnord=42, *args, **kwargs):
    self.super(*args, **kwargs)

これはあなたが望むことをしますか?

def foo(self, fnord=42, *args, **kwargs):
    self.super(fnord=fnord, *args, **kwargs)
于 2010-03-27T14:46:34.820 に答える