Skip to main content
 首页 » 编程设计

Python 3.2 语法规范——函数调用

2025年05月04日17Terrylee

这是对 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 

据此,基本函数调用可能如下所示:

原子 '(' ')'

但我相信我们不能只把 any atom 放在那里。例如,即使 1 是一个 atom (NUMBER),1 也不是一个函数,因此您不能用 1() 之类的东西调用它。我的问题是:给定 power 语法规则的一个实例,它的 atom 是否可以替换为 atom 的任何规则而不是 NAME 在 Python 程序的解析树中并且仍然运行?

编辑(答案):

任何“可调用”的东西都可以用 () 运算符调用。 ( http://docs.python.org/py3k/reference/expressions.html#calls ):

call ::=  primary "(" [argument_list [","] | comprehension] ")" 

The primary must evaluate to a callable object (user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances, and all objects having a __call__() method are callable).

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

>>> 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 

请您参考如下方法:

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

请注意,这里的错误是 TypeError 而不是 SyntaxError。尝试调用号码是完全合法的语法;号码只是没有任何实际调用功能。