【发布时间】:2012-04-03 04:19:32
【问题描述】:
这是对 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
据此,一个基本的函数调用可能如下所示:
atom '(' ')'
但我相信我们不能只是把 any atom 放在那里。例如,即使1 是atom (NUMBER),1 也不是函数,因此您不能使用1() 之类的名称调用它。我的问题是:给定一个power 语法规则的实例,它的atom 是否可以在Python 程序的解析树中被atom 的任何规则替换而不是NAME 并且仍然运行?
编辑(回答):
任何“可调用”的东西都可以用() 操作符调用。 (http://docs.python.org/py3k/reference/expressions.html#calls):
call ::= primary "(" [argument_list [","] | comprehension] ")"
primary必须评估为可调用对象(用户定义的函数、内置函数、内置对象的方法、类对象、类实例的方法,以及所有具有__call__()方法的对象都是可调用的)。
这意味着您可以执行以下操作:
>>> eval.__call__.__call__("print(\"x\")")
x
甚至更疯狂(无用)的东西:
>>> a = lambda x : [abs, lambda y : y][0 if x < 0 else 1](x)
>>> a(1)
1
>>> a(-1)
1
>>> a(0)
0
【问题讨论】:
-
简单的答案是“是”。您需要设置更多限制。
-
您的“EDIT(ANSWER)”示例实际上与您的问题没有太大关系;它们都没有被解析为
atom,后跟调用括号。像[func][0]()这样的东西是atom[func]后跟一个预告片[0]后跟另一个预告片()。 -
@Ben,是的,我现在看到这些示例实际上是
trailers 而不是atoms。 EDIT(ANSWER) 适用于一个稍微不同的问题,我在进行编辑之前在评论中提出了这个问题(“我想知道除了函数名称之外可以在函数调用之前立即放置哪些类型的东西,并且有它实际上运行而不仅仅是解析。”)。我是社区的新手,明白你的意思。就编辑我的问题或保持不变而言,此时应该做什么?
标签: python compiler-construction grammar