2009-10-13 25 views
3

我正在編寫一個使用遺傳技術來演化方程的程序。 我希望能夠將函數'mainfunc'提交給並行Python'提交'功能。 函數'mainfunc'調用Utility類中定義的兩個或三個方法。 他們實例化其他類並調用各種方法。 我想我想要的是它在一個NAMESPACE中。 所以我實例化了函數mainfunc中的一些類(也許它應該是全部)。 我稱之爲Utility方法'generate()'。如果我們要遵循它的執行鏈 它將涉及代碼中的所有類和方法。構建一個程序。 Python中的類和函數

現在,方程存儲在一棵樹中。每次生成樹,突變或交叉時,都需要給節點一個新的密鑰,以便可以從樹的字典屬性中訪問它們。類'KeySeq'生成這些密鑰。

在並行Python中,我將發送多個'mainfunc'實例給PP的'submit'函數。每個人都必須能夠訪問'KeySeq'。如果他們都訪問相同的KeySeq實例,以便返回的樹上沒有任何節點具有相同的密鑰,但如果有必要,我可以解決這個問題。

所以:我的問題是關於將所有東西塞進mainfunc。 謝謝 (編輯)如果我沒有在mainfunc中包含所有東西,我必須通過在各個地方傳遞各種論證來嘗試告訴PP相關函數等。我試圖避免這種情況。

(後期編輯)如果ks.next()被稱爲「的內部產生()函數,則返回錯誤‘NameError:全球名‘KS’沒有定義’

class KeySeq: 
    "Iterator to produce sequential \ 
    integers for keys in dict" 
    def __init__(self, data = 0): 
     self.data = data 
    def __iter__(self): 
     return self 
    def next(self): 
     self.data = self.data + 1 
     return self.data 
class One: 
    'some code' 
class Two: 
    'some code' 
class Three: 
    'some code' 
class Utilities: 
    def generate(x): 
     '___________' 
    def obfiscate(y): 
     '___________' 
    def ruminate(z): 
     '__________' 


def mainfunc(z): 
    ks = KeySeq() 
    one = One() 
    two = Two() 
    three = Three() 
    utilities = Utilities() 
    list_of_interest = utilities.generate(5) 
    return list_of_interest 

result = mainfunc(params) 

回答

1

如果你希望所有的mainfunc實例中使用相同的KeySeq對象,你可以使用默認參數值的技巧:

def mainfunc(ks=KeySeq()): 
    key = ks.next() 

只要你不實際的ks值傳遞,所有對mainfunc的調用都將使用在定義函數時創建的KeySeq實例。

這是爲什麼,如果你不知道:函數是一個對象。它具有屬性。其中一個屬性名爲func_defaults;它是一個包含其簽名中具有缺省值的所有參數的默認值的元組。當您調用一個函數並且沒有爲具有缺省值的參數提供值時,該函數將從func_defaults中檢索該值。因此,當您撥打mainfunc而未提供ks的值時,它會從func_defaults元組中獲取KeySeq()實例。其中,對於mainfunc的實例,始終是相同的KeySeq實例。

現在,你說你打算髮送「mainfunc的多個實例到PP的submit函數。「你真的意味着多個實例嗎?如果是這樣,我描述的機制將不起作用。

但是創建一個函數的多個實例(以及你發佈的代碼沒有)是非常棘手的。例如,這個函數每次它被稱爲時間返回g一個新實例:

>>> def f(): 
     def g(x=[]): 
      return x 
     return g 
>>> g1 = f() 
>>> g2 = f() 
>>> g1().append('a') 
>>> g2().append('b') 
>>> g1() 
['a'] 
>>> g2() 
['b'] 

如果我打電話g()不帶參數,它從func_defaults元組返回默認值(初始列表爲空)由於g1g2g函數的不同實例,它們的參數x的默認值是也是一個不同的實例,上面的演示。

如果你想使這更明確的比使用默認值的一個棘手的副作用,這裏是另一種方式來做到這一點:

高清mainfunc(): 如果沒有hasattr(mainfunc,「KS 「): SETATTR(mainfunc, 「KS」,KeySeq()) 鍵= mainfunc.ks.next()

最後,你的代碼已經發布俯瞰超級重要的一點:如果你打算要對共享數據進行並行處理,觸及該數據的代碼需要實現鎖定。查看Parallel Python文檔中的callback.py示例,並查看Sum類中如何使用鎖定以及爲什麼。

+0

我試着插入你的'默認參數技巧'。 我在'utilities.generate()方法中得到了一個錯誤: a = key 「NameError:全局名稱'key'未定義」 我確定'mainfunc(ks = KeySeq())'參數。 現在我試圖讓這個工作不參考PP。 但是,我會研究你的消息的後半部分。在引入PP之前,我會參考callback.py。 – 2009-10-14 17:09:09

+0

我也嘗試了第二種方法建議,'更明確'。 它在同一個'utilities.generate()方法中產生了相同的錯誤。 – 2009-10-14 19:23:52

+1

聽起來好像你錯誤地理解'key'在'mainfunc'函數之外是可見的。它不會被'Utilities.generate()'使用,除非你做了一些事情使它成爲一個'generate'函數的參數,或者將它傳遞給構造函數,或者在'實例化它之後的Utilities對象。或者使其成爲模塊級變量並使用'global'引用它。有幾十種方法可以做到這一點,但你必須使用其中之一。 – 2009-10-15 06:34:12

3

它的優良以這種方式構建你的程序。很多命令行實用程序遵循相同的模式:

#imports, utilities, other functions 

def main(arg): 
    #... 

if __name__ == '__main__': 
    import sys 
    main(sys.argv[1]) 

這樣,你可以通過導入它從另一個調用模塊main功能,或者你可以在命令行中運行它。

+0

注意到。謝謝 – 2009-10-14 16:55:41

0

我認爲你在Python中的類的概念是不正確的。也許,這是一個好主意,審查的基礎知識。此鏈接將有所幫助。

Python Basics - Classes

+0

你是對的。感謝您的鏈接 – 2009-10-17 16:51:40

相關問題