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)
>>> 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.尝试拨号是完全合法的语法 ; 数字只是没有任何实际的通话功能.