2017-03-18 53 views
-1

在某些情況下,它可用於從Python腳本(可能來自不可信任的源)讀取數據,並從中提取值。如何在不執行Python腳本的情況下提取變量?

儘管在大多數情況下XML/JSON/YAML/TOML等格式更適合,但有時候這樣做有用。

如何從Python腳本中提取變量名&而不執行它?
(假設值結構不包含代碼執行他們的創作)

回答

1

這可以使用Python的AST模塊來完成:

這個例子功能從文件中讀取一個單一命名的變量。

當然這需要變量可以使用ast.literal_eval()進行評估。

def safe_eval_var_from_file(mod_path, variable, default=None, *, raise_exception=False): 
    import ast 
    ModuleType = type(ast) 
    with open(mod_path, "r", encoding='UTF-8') as file_mod: 
     data = file_mod.read() 

    try: 
     ast_data = ast.parse(data, filename=mod_path) 
    except: 
     if raise_exception: 
      raise 
     print("Syntax error 'ast.parse' can't read %r" % mod_path) 
     import traceback 
     traceback.print_exc() 
     ast_data = None 

    if ast_data: 
     for body in ast_data.body: 
      if body.__class__ == ast.Assign: 
       if len(body.targets) == 1: 
        if getattr(body.targets[0], "id", "") == variable: 
         try: 
          return ast.literal_eval(body.value) 
         except: 
          if raise_exception: 
           raise 
          print("AST error parsing %r for %r" % (variable, mod_path)) 
          import traceback 
          traceback.print_exc() 
    return default 


# Example use, read from ourself :) 
that_variable = safe_eval_var_from_file(__file__, "this_variable") 
this_variable = {"Hello": 1.5, b'World': [1, 2, 3], "this is": {'a set'}} 
assert(this_variable == that_variable) 
相關問題