从字典中解压缩Sympy变量

时间:2016-03-09 11:15:39

标签: python function dictionary arguments sympy

我正在制作一个计划,为我的微观经济学课程做一些计算。由于根据我给出的问题有一些工作方式,我创建了一个类。该类从命令行解析Utility函数和'mode',并根据模式调用函数或其他函数。 由于每个函数都使用相同的变量,因此我在__init__()中启动它们:

self.x = x = Symbol('x')  # Variables are initiated
self.y = y = Symbol('y')
self.Px, self.Py, self.m = Px, Py, m = Symbol('Px'), Symbol('Py'), Symbol('m')

我需要一个本地定义来成功处理该功能。通过sympify()启动函数后,我将其保存为实例变量:

self.function = sympify(args.U) 

现在我需要将变量x,yPx,Py,m传递给不同的函数。这就是我遇到问题的地方。由于我想要一个本地定义,我可以简单x=self.x包含所有变量。我需要在每一段不可持续的代码中重复这一点。另一种选择是将所有变量作为参数传递。

但是因为我使用字典来选择调用哪个函数取决于模式,这意味着我必须为每个函数传递相同的参数,无论我是否使用它们。

所以我决定创建一个字典,例如:

variables = {          #A dictionary of variables is initiated
        'x':self.x,
        'y':self.y,
        'Px':self.Px,
        'Py':self.Py,
        'm':self.m
        }

在我将变量声明为sympy Symbols后启动此词典。我想要的是将这个字典以解压缩的形式传递给每个函数。这样我只需要**kwargs作为参数,我可以使用我想要的变量。

我想要的是这样的:

a = 3
arggs = {'a' = a}
def f(**kwargs):return a+1
f(**args)

返回4.但是当我将字典作为参数传递时,我得到一个未定义的'x'或'y'变量错误。它不能是范围问题,因为已为所有实例启动了所有变量。

这是我调用函数的代码:

 self.approaches[self.identification][0](**self.variables)
 def default(self, **kwargs):
     solutions = dict()
     self.MRS = S(self.function.diff(x) / self.function.diff(y))   # This line provokes the exception

我的错误是什么?

PS:有些信息可能不清楚。英语不是我的主要语言。提前道歉。

1 个答案:

答案 0 :(得分:1)

不幸的是,Python并不像那样。当您使用**kwargs时,它指定的唯一变量是变量kwargs,它是关键字参数的字典。通常,由于本地名称空间的工作方式,没有简单的方法将名称注入函数的本地名称空间。有办法做到这一点,但他们相当hacky。

使变量可用而不必每次都定义它们的最简单方法是在模块级别定义它们。一般来说,这是一种不好的做法(它确实 属于该类),但由于SymPy符号是不可变的并且完全由它们的名称定义(如果你设置了任何假设),它就可以了。设置

Px, Py, m = symbols("Px Py m")

在模块级别(即,在您的类定义之上),因为即使某个其他函数定义了自己的Symbol("Px"),SymPy也会认为它等于您之前定义的Px

一般来说,你可以用这种方式快速松散地使用不可变对象(并且所有SymPy对象都是不可变的),因为如果一个不可变对象被另一个相等的对象替换它并不重要。重要的是,如果你有一个列表(一个可变容器),因为如果它在模块级别上定义,而不是类级别与实例级别相比,它会产生很大的不同。

相关问题