我正在Python中動態生成代碼。什麼是Python AST中的Expr?
爲了解決這個問題,我編寫了一個輔助方法,它接收一串Python代碼並轉儲AST。下面是一個方法:
# I want print treated as a function, not a statement.
import __future__
pfcf = __future__.print_function.compiler_flag
from ast import dump, PyCF_ONLY_AST
def d(s):
print(dump(compile(s, '<String>', 'exec', pfcf|PyCF_ONLY_AST))
當我運行一個簡單的Hello World這個功能,它吐出以下(格式爲便於閱讀):
d("print('Hello World!')")
Module(body=[Expr(value=Call(func=Name(id='print',
ctx=Load()),
args=[Str(s='Hello World!')],
keywords=[],
starargs=None,
kwargs=None))])
我能夠動態生成此代碼,運行它 - 一切都很棒。
然後我試圖動態生成
print(len('Hello World!'))
應該是很容易 - 只是一個函數調用。下面是我的代碼動態生成的:
Module(body=[Expr(value=Call(func=Name(id='print',
ctx=Load()),
args=[Expr(value=Call(func=Name(id='len',
ctx=Load()),
args=[Str(s='Hello World!')],
keywords=[],
starargs=None,
kwargs=None))],
keywords=[],
starargs=None,
kwargs=None))])
雖然運行它沒有工作。相反,我得到這個消息:
TypeError: expected some sort of expr, but got <_ast.Expr object at 0x101812c10>
於是我就前面提到的我的helper方法,看看它會輸出:
d("print(len('Hello World!')")
Module(body=[Expr(value=Call(func=Name(id='print',
ctx=Load()),
args=[Call(func=Name(id='len',
ctx=Load()),
args=[Str(s='Hello World!')],
keywords=[],
starargs=None,
kwargs=None)],
keywords=[],
starargs=None,
kwargs=None))])
之間什麼我產生(不工作的區別)和它產生的(它的工作原理)是他們直接將Call
傳遞給args,而我把它包裝在Expr
中。
問題是,在第一行中,我需要將Call
換成Expr
。我很困惑 - 爲什麼有時需要將Call
換成Expr
而不是其他時間? Expr
似乎應該只是Call
繼承的抽象基類,但是它在Module
之下的頂級級別中是必需的。爲什麼?我錯過了些微妙的東西嗎?當Call
需要包裝在Expr
中以及什麼時候可以直接使用?
感謝您的聯繫 - 它看起來會是這個項目非常有價值。 – ArtOfWarfare