Python:从包含表达式的字符串中动态初始化类成员

时间:2019-06-28 19:12:57

标签: python dynamic python-exec

这是一个非常普通的场景,但是为了提供一些背景信息,假设我使用Declare date, then add next business day进行了一些约束优化。现在说我想在运行时提供目标函数,例如下面的func

import cvxpy as cp

class foo:
  def __init__(self,n,q,s):
    self.n,self.q,self.s=n,q,s
    self.K = len(n)
    self.x = cp.Variable(self.K)
    self.func = cp.sum(sum(self.n[j]*sum(self.n[i]*self.x[j] for i in range(self.K)) for j in range(self.K))

当然,示例中的函数是人为设计的,仅用于示例 什么样的 我愿意提供的字符串表达式作为命令行参数, 只是为了避免硬编码东西/一直更改源代码。如何在运行时用新值覆盖此func成员的值?我读过有关exec的内容,但不确定是否有帮助。简而言之,我愿意做类似python my_awesom_prog.py "self.n[i]*self.n[j] for i in range(self.K) for range(self.K)"的事情,并且我希望程序的行为就像最初定义func时那样(可怕的)字符串一样。 编辑:更重要的是,我想有一个像这样的方法:

def reset_objective(mystring):
   self.func = interpret_as_cvxpy_entity(mystring)

现在,如何掌握该interpret_as_cvxpy_entity API?

1 个答案:

答案 0 :(得分:0)

您可以使用input()eval()。因此,类似:

import cvxpy as cp

class foo:
  def __init__(self,n,q,s):
    self.n,self.q,self.s=n,q,s
    self.K = len(n)
    self.x = cp.Variable(self.K)
    self.func = eval(input())

然后,您可以以python my_awesom_prog.py"self.n[i]*self.n[j] for i in range(self.K) for range(self.K)"作为输入来运行脚本。

我应该警告您eval(input())的危险。例如,您可以在eval函数中输入代码,以删除计算机上的每个文件。有关为何不应该执行此操作的更多信息,请参考以下文章:

https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html