2016-03-09 46 views
1

我正在爲我的微觀經濟學課程做一些計算。由於根據我給出的問題有一些工作方式,所以我創建了一個班級。該類從命令行解析實用程序函數和「模式」,並根據模式調用函數或其他函數。 由於每個函數使用相同的變量我開始他們__init__()從字典中解壓縮Sympy變量

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

不幸的是,Python並不像那樣工作。當您使用**kwargs時,此分配的唯一變量是變量kwargs,它是關鍵字參數的字典。通常,由於本地名稱空間的工作方式,沒有簡單的方法將名稱注入到函數的本地名稱空間中。有辦法做到這一點,但他們很hacky。

使變量可用而無需每次定義它們的最簡單方法是在模塊級別定義它們。一般來說,這是有點不好的做法(這真的屬於這個類),但由於SymPy符號是不變的,通過他們的名字(如果你設置任何和假設)完全定義,它設置只是罰款

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

(即,在您的類定義之上),因爲即使某些其他函數定義了它自己的Symbol("Px"),SymPy也會認爲它等於您之前定義的Px

通常情況下,你可以用這種方式對不可變對象進行一些快速和鬆散的處理(並且所有的SymPy對象都是不可變的),因爲如果一個不可變的對象被另一個相等的對象所取代並不重要。如果你說有一個列表(一個可變容器),那麼這很重要,因爲如果它在模塊級別上與類級別和實例級別上定義相比將會產生很大的差異。