从字典中解压 Sympy 变量
Unpacking Sympy variables from dictionary
我正在编写一个程序来为我的微观经济学做一些计算 class。由于根据我遇到的问题有一些工作方法,因此我创建了一个 class。 class 从命令行解析实用程序函数和 '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)
This returns 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:部分信息可能不清楚。英语不是我的主要语言。提前致歉。
不幸的是,Python 并不是那样工作的。当您使用 **kwargs
时,它分配的唯一变量是变量 kwargs
,它是关键字参数的字典。通常,由于本地名称空间的工作方式,没有简单的方法可以将名称注入函数的本地名称空间。有很多方法可以做到这一点,但它们相当笨拙。
使变量可用而不必每次都定义它们的最简单方法是在模块级别定义它们。一般来说,这是有点不好的做法(它确实 属于 class),但是由于 SymPy 符号是不可变的并且完全由它们的名称定义(以及假设,如果你设置any),设置
就好了
Px, Py, m = symbols("Px Py m")
在模块级别(即,在您的 class 定义之上),因为即使某些其他函数定义了它自己的 Symbol("Px")
,SymPy 也会认为它等于您的 Px
从之前定义的。
一般来说,您可以通过这种方式快速而随意地使用不可变对象(并且所有 SymPy 对象都是不可变的),因为如果一个不可变对象被第二个相等的对象替换并不重要。如果你有一个列表(一个可变容器),那会很重要,因为如果它是在模块级别、class 级别和实例级别定义的,那将产生很大的不同。
我正在编写一个程序来为我的微观经济学做一些计算 class。由于根据我遇到的问题有一些工作方法,因此我创建了一个 class。 class 从命令行解析实用程序函数和 '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)
This returns 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:部分信息可能不清楚。英语不是我的主要语言。提前致歉。
不幸的是,Python 并不是那样工作的。当您使用 **kwargs
时,它分配的唯一变量是变量 kwargs
,它是关键字参数的字典。通常,由于本地名称空间的工作方式,没有简单的方法可以将名称注入函数的本地名称空间。有很多方法可以做到这一点,但它们相当笨拙。
使变量可用而不必每次都定义它们的最简单方法是在模块级别定义它们。一般来说,这是有点不好的做法(它确实 属于 class),但是由于 SymPy 符号是不可变的并且完全由它们的名称定义(以及假设,如果你设置any),设置
就好了Px, Py, m = symbols("Px Py m")
在模块级别(即,在您的 class 定义之上),因为即使某些其他函数定义了它自己的 Symbol("Px")
,SymPy 也会认为它等于您的 Px
从之前定义的。
一般来说,您可以通过这种方式快速而随意地使用不可变对象(并且所有 SymPy 对象都是不可变的),因为如果一个不可变对象被第二个相等的对象替换并不重要。如果你有一个列表(一个可变容器),那会很重要,因为如果它是在模块级别、class 级别和实例级别定义的,那将产生很大的不同。