Python C API-如何为评估表达式赋值?

时间:2018-08-31 13:48:49

标签: python c eval python-c-api

是否可以在不操纵评估字符串的情况下将值分配给“评估表达式”?示例:用户编写表达式

"globalPythonArray[10]"

它将评估为globalPythonArray项目10的当前值。但目标是将项目10的值设置为新值,而不是获取旧值。一个肮脏的解决方法是,定义一个临时变量“ newValue”并将评估字符串扩展为

"globalPythonArray[10] = newValue"

并编译和评估该修改后的字符串。是否有一些我可以使用的低级Python C API函数,而不必操纵评估字符串?

2 个答案:

答案 0 :(得分:1)

我可能不会说,因为访问和存储订阅是不同的操作码:

findByName

System.out.println(table+"x1= ?");
r =sc.nextInt();
if(r == table*1) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;
}
System.out.println(table+"x2= ?");
r =sc.nextInt();
if(r == table*2) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x3= ?");
r =sc.nextInt();
if(r == table*3) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x4= ?");
r =sc.nextInt();
if(r == table*4) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x5= ?");
r =sc.nextInt();
if(r == table*5) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x6= ?");
r =sc.nextInt();
if(r == table*6) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x7= ?");
r =sc.nextInt();
if(r == table*7) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x8= ?");
r =sc.nextInt();
if(r == table*8) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x9= ?");
r =sc.nextInt();
if(r == table*9) {
    System.out.println("Correct");
    p +=1;
}else {
    System.out.println("Error");
    e +=1;}
System.out.println(table+"x10= ?");
r =sc.nextInt();
if(r == table*10) {
    System.out.println("Correct\n");
    p +=1;
}else {
    System.out.println("Error\n");
    e +=1;
}

此外,在此处插入有关用户输入的常规警告,并在此处插入out = /location/of/test.txt file = open(out,'w') df = some dataframe df[:,4] = [7,12,1,35,4] for col in range(len(df.index)): a = randint(1,10) file.write('%i ' % a) b = randint(1,10) file.write('%i ' % b) c = (df.iloc[[col],4]) file.write('%.i ' % c) file.write('\n')

>>> dis.dis(compile('globalPythonArray[10]', 'a', 'exec'))
  1           0 LOAD_NAME                0 (globalPythonArray)
              2 LOAD_CONST               0 (10)
              4 BINARY_SUBSCR
              6 POP_TOP
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE

答案 1 :(得分:0)

可以通过操纵其抽象语法树(AST)将值“分配”给评估表达式。不必直接修改评估字符串,如果新值的类型不太复杂(例如,数字或字符串),则可以将其硬编码到AST中:

  • 将eval表达式编译为AST。
  • 通过 Store 替换根节点上的 Load 表达式上下文。
  • 在根节点上使用 Assign 语句创建新的AST。
  • target 设置为修改后的eval AST的表达式节点。
  • 设置为该值。
  • 将新的AST编译为字节码并执行。

示例

import ast
import numpy as np


def eval_assign_num(expression, value, global_dict, local_dict):
    expr_ast = ast.parse(expression, 'eval', 'eval')
    expr_node = expr_ast.body
    expr_node.ctx = ast.Store()

    assign_ast = ast.Module(body=[
        ast.Assign(
            targets=[expr_node],
            value=ast.Num(n=value)
        )
    ])
    ast.fix_missing_locations(assign_ast)

    c = compile(assign_ast, 'assign', 'exec')
    exec(c, global_dict, local_dict)


class TestClass:
    arr = np.array([1, 2])
    x = 6


testClass = TestClass()
arr = np.array([1, 2])

eval_assign_num('arr[0]', 10, globals(), locals())
eval_assign_num('testClass.arr[1]', 20, globals(), locals())
eval_assign_num('testClass.x', 30, globals(), locals())
eval_assign_num('newVarName', 40, globals(), locals())

print('arr', arr)
print('testClass.arr', testClass.arr)
print('testClass.x', testClass.x)
print('newVarName', newVarName)

输出

arr [10  2]
testClass.arr [ 1 20]
testClass.x 30
newVarName 40