2017-04-23 33 views
0

我需要將修改後的python對象轉儲回源代碼。因此,我試圖找到一些真正的Python對象轉換爲蟒蛇ast.Node(後來使用astor LIB轉儲源)使用的將python對象轉換爲python AST節點

例子我想,Python的2:

import ast 
import importlib 

import astor 


m = importlib.import_module('something') 

# modify an object 
m.VAR.append(123) 

ast_nodes = some_magic(m) 

source = astor.dump(ast_nodes) 

請幫我發現some_magic

+1

爲什麼?這看起來就像是你描述你想要的解決方案,而不是問題本身。如果我不得不冒險猜測,那麼下一次代碼運行時,您正試圖保持對象的狀態。這是將對象序列化爲JSON格式並將其保存到文件中的完美場景!然後,當代碼再次運行時,您只需從該文件反序列化即可。 – Aaron3468

+0

好吧,可以通過。 問題 - 我想通過生成模板模型,表單,模板,視圖,url來加速開發簡單的django頁面。 而問題是修改Django的URL。這是一個列表。所以我不能只在文件末尾寫。 – Vladimir

+0

使用'pickle',JSON等序列化格式 –

回答

1

沒有辦法做你想做的事,因爲那不是AST如何工作。 當解釋器運行你的代碼時,它會從源文件中生成一個AST,並且解釋爲 AST生成python對象。 這些對象一旦生成就會發生什麼事,與AST無關。

然而,有可能首先獲得生成對象的AST。 模塊inspect讓你得到一些Python對象的源代碼:

import ast 
import importlib 
import inspect 

m = importlib.import_module('pprint') 
s = inspect.getsource(m) 
a = ast.parse(s) 
print(ast.dump(a)) 
# Prints the AST of the pprint module 

getsource()被恰當地命名。 如果我要更改m中的某個變量(或任何其他對象)的值,它將不會更改其源代碼。

即使有可能從對象中重新生成AST,也不會有可返回的單個解決方案some_magic()。 想象我有一些模塊變量x,我在另一個模塊中重新分配:

# In some_module.py 
x = 0 

# In __main__.py 
m = importlib.import_module('some_module') 
m.x = 1 + 227 

現在,m.x228,但沒有辦法知道導致該值什麼樣的表情(井,沒有閱讀AST的__main__.py,但這很快就會失控)。這僅僅是文字嗎?函數調用的結果?

如果您在修改某個模塊的某個值之後確實需要獲取新的AST,那麼最好的解決方案是自行轉換原始AST。 你可以找到你的標識符的價值,並用任何你想要的值代替任務的價值。 舉例來說,在我的小例子x = 0由以下AST表示:

Assign(targets=[Name(id='x', ctx=Store())], value=Num(n=0)) 

並獲得AST匹配調動我__main__.py做,我將不得不改變上述Assign節點作爲價值以下:

value=BinOp(left=Num(n=1), op=Add(), right=Num(n=227)) 

如果你想一直這樣下去,我建議你檢查AST節點變壓器(ast.NodeTransformer)的Python的文檔,以及該文檔可以在Python滿足所有節點本優秀手冊ASTs Green Tree Snakes - the missing Python AST docs