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 的超级,但仍然不是很好,它不适用于 Python 2.x...

更新 2

实际上,即使 Python 的 ast 模块也删除了**{}( ast.parse('foo(**{})')),所以看起来这种情况发生在解析过程的早期,以至于您以后无法获得此信息......

所以最后我要么放弃那个特定的问题(引发 AmbiguousSyntaxError),要么使用 ~unutbu 提出的文本解析。重新考虑我的方法,后者实际上可能是可行的,因为我只需要知道它是否是self.super(\s*), self.super(\S+).

4

3 回答 3

0

此 hack 仅适用于 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仅使用 value 调用x它,但它会打印变量的“名称”(因为它被调用)和变量的值。有时我在调试时使用它并且懒得写出完整的打印语句。

于 2010-03-27T13:56:28.010 回答
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 回答
0

所以基本上不可能用提供的 Python 模块来做到这一点。鉴于我的要求很简单,我不得不退回到对我来说非常有效的纯文本正则表达式。

于 2010-04-17T10:24:09.983 回答