Python 3.2语法规范 - 函数调用

Wor*_*red 1 python compiler-construction grammar

这是参考Python 3.2.相关语法规则如下(http://docs.python.org/py3k/reference/grammar.html):

power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_comp] ')' |
       '[' [testlist_comp] ']' |
       '{' [dictorsetmaker] '}' |
       NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Run Code Online (Sandbox Code Playgroud)

根据这个,基本函数调用可能看起来像:

atom '(' ')'

但我相信,我们不能只是把任何 atom在那里.例如,即使1是一个atom(NUMBER),1也不是一个函数,因此你不能用类似的东西来调用它1().我的问题是:给定一个power语法规则的实例,它atom可以用atom除了NAMEPython程序的解析树之外的任何规则替换并仍然运行吗?

编辑(答案):

可以与()操作员一起调用任何"可调用"的东西.(http://docs.python.org/py3k/reference/expressions.html#calls):

call ::=  primary "(" [argument_list [","] | comprehension] ")"
Run Code Online (Sandbox Code Playgroud)

primary结果必须为可调用对象(用户定义的函数,内置函数,内置对象的方法,对象类,类的实例的方法,以及具有的所有对象__call__()的方法是可调用).

这意味着您可以执行以下操作:

>>> eval.__call__.__call__("print(\"x\")")
x
Run Code Online (Sandbox Code Playgroud)

甚至更疯狂(无用)的东西:

>>> a = lambda x : [abs, lambda y : y][0 if x < 0 else 1](x)
>>> a(1)
1
>>> a(-1)
1
>>> a(0)
0
Run Code Online (Sandbox Code Playgroud)

Amb*_*ber 7

>>> 1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>>
Run Code Online (Sandbox Code Playgroud)

请注意,此处的错误是a TypeError而不是a SyntaxError.尝试拨号是完全合法的语法 ; 数字只是没有任何实际的通话功能.