簡體   English   中英

Python-傳遞變量句柄進行評估

[英]Python - Pass variable handle to evaluate

我正在使用python和z3py模塊編寫一些程序。
我要執行的操作如下:我從位於其他文件中的函數中提取if或while語句的約束。 另外,我提取了語句中使用的變量及其類型。
由於我不想手動將約束解析為z3py友好形式,因此我嘗試使用評估為我完成此操作。 因此,我使用了以下頁面的技巧: 帶字符串表達式的Z3
現在的問題是:我不知道如何調用約束中的變量。 但似乎我必須像實際變量一樣命名每個變量的句柄。 否則評估將找不到它。 我的代碼如下所示:

solver = Solver()
# Look up the constraint:
branch = bd.getBranchNum(0)
constr = branch.code
# Create handle for each variable, depending on its type:
for k in mapper.getVariables():
    var = mapper.getVariables()[k]
    if k in constr:
        if var.type == "intNum":
            Int(k)
        else:
            Real(k)
# Evaluate constraint, insert the result and solve it:
f = eval(constr)
solver.insert(f)
solve(f)

如您所見,我將變量和約束保存在類中。 執行此代碼時,出現以下錯誤:

NameError: name 'real_x' is not defined

如果我不使用循環遍歷變量,而是使用以下代碼,則一切正常:

solver = Solver()
branch = bd.getBranchNum(0)
constr = branch.code
print(constr)
real_x = Real('real_x')
int_y = Int('int_y')
f = eval(constr)
print(f)
solver.insert(f)
solve(f)

問題是:我不知道這些變量稱為“ real_x”還是“ int_y”。 此外,我不知道使用了多少變量,這意味着我必須使用一些動態的東西,例如循環。

現在我的問題是:有辦法解決嗎? 我該怎么做才能告訴python句柄已經存在,但是名稱不同? 還是我的方法完全錯誤,我必須做一些完全不同的事情?

這種事情幾乎總是一個壞主意(有關更多詳細信息,請參閱為什么eval / exec不好 ),但是“幾乎總是”不是“總是”,並且看起來您正在使用專門設計用於以這種方式使用,在這種情況下,您會發現一個例外。

乍一看,您似乎碰到了“ 將數據保留在變量名之外”准則的罕見例外之一(另請參閱為什么不希望動態創建變量 )。 但是你沒有。

您需要像real_x這樣的變量存在的唯一原因是,以便eval可以看到它們,對嗎? 但是eval函數已經知道如何在字典中而不是在全局名稱空間中查找變量。 看起來您從mapper.getVariables()是一本字典。

因此,跳過整個混亂的循環,然后執行以下操作:

variables = mapper.getVariables()
f = eval(constr, globals=variables)

(在Python的早期版本中, globals是僅位置參數,因此,如果遇到有關此錯誤的信息,請刪除globals= 。)

如文檔所述,這使eval函數可以訪問您的實際變量,以及mapper想要生成的變量,並且它可以執行各種不安全的操作。 如果要防止不安全的事情,請執行以下操作:

variables = dict(mapper.getVariables())
variables['__builtins__'] = {}
f = eval(constr, globals=variables)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM