2012-01-31 48 views
0

我想保留一個函數迭代中保存的結構,以便保留數據以備後用。 使用全局變量有一個簡單的方法。通過迭代在函數中保持結構「活着」?

問題是,任何人都可以訪問該變量。 那麼,有沒有辦法創建一個只能由函數訪問的變量,但是在運行此函數時不會被擦除?

例:

mylist = [] 

def test(): 
    global mylist 

    if mylist: 
     my_list.append(1) 

    other_stuff, using my_list 

正是我想做的事,但my_list可能被其他人訪問。

(好吧我知道的例子是完全啞)

很抱歉的提法,但我不能來的東西簡單

編輯:好了,所以有這麼不同的(和所有有趣的)解決方案。我會很快解釋我想做什麼的想法:)

讓我們想象一下,我想要計算的是一個數字是素數。這通常是計算性的。

所以我得到了一個is_prime(value)函數,返回False或True。

值可以是任何數字,但有機會(在我的情況下)該值需要幾次相同的值(litteraly ^^)。

在這種情況下,我可以使用我已經發現的素數列表(不要太長)來快速檢查和保存計算。 但是我的prime_list在返回true/false的函數中沒有用處。

所以這裏是我的問題:)。

希望澄清一些思想(包括我!)。

+0

爲什麼不是這個結構的函數參數?這難道不是很簡單嗎? – 2012-01-31 21:47:11

+0

http://stackoverflow.com/questions/279561/what-is-the-python-equivalent-of-static-variables-inside-a-function – 2012-01-31 21:49:56

+0

的潛在重複是和否。如我的例子所示,這個變量可能是/或不存在的。如果有參數,這個列表將出現在代碼的其他地方。我想避免 – jlengrand 2012-01-31 21:50:41

回答

3

這裏是一個列表作爲參數的默認值就可以派上用場的情況下:

def test(myList=[]): 

    myList.append(1) 
    other_stuff, using myList 

我離開if myList,因爲它會存在(它是在定義test時創建的)。 (另外,if myList測試列表是否非空,未定義)。

myList作爲函數參數,是本地的test。當定義test時,它被初始化爲一個列表。該列表的價值在您的程序的生命中持續存在。

比較於

def test(myList = None): 
    if myList is None: 
     myList = [] 

的標準建議,當你想裏面test在每次調用一個新的空列表,如果是通過在呼叫沒有提供列表,它是必要的。

+1

這非常聰明。我不得不說,這是對Python的一種「濫用」,意味着這是可能的.OP正在做一些可能以另一種方式做得更好的事情。 – 2012-01-31 22:09:59

+0

是什麼讓你把它歸類爲濫用?我在裝飾器和默認字典參數之間徘徊,這是Python中記憶的最佳成語。 – 2012-02-01 01:04:32

+0

我同意這是一個輕微的濫用,因爲它是一個函數參數,除了它的默認值以外不會被使用。一個問題是,如果'* args'在你的函數簽名中,你就不能使用這個技巧,因爲myList會在'args'接收到任何參數之前接收到其中一個參數。 – chepner 2012-02-01 14:17:03

1

您可以在「靜態變量」添加到功能如下:

>>> def fun(x): 
... fun.counter += x 
... print fun.counter 
>>> fun.counter = 0 
>>> fun(1) 
1 
>>> fun(5) 
6 
+0

'fun.counter'仍然可以從外部獲得樂趣,如初始化所示。 – chepner 2012-01-31 21:52:20

+0

恥辱,因爲我喜歡這個主意:) – jlengrand 2012-01-31 21:56:52

+1

是的,但是這確實避免了全局命名空間中的潛在衝突,我認爲這是全局變量的主要問題。然而,正如我在OP上評論的那樣,我承認我可能會誤解這個問題。通常在Python中,人們不會費心地隱藏其他程序員的數據......但顯然你不想污染全局命名空間,因此人們可能意外地覆蓋了你的變量。 – 2012-01-31 21:57:19

1

一種解決辦法是把它包在另一個功能:

def make_tester(): 
    mylist = [] 

    def test(): 
     if mylist: 
      my_list.append(1) 

     # other_stuff, using my_list 
    return test 

test = make_tester() 

這招在小的開銷,你必須先調用測試創建將在稍後調用的函數。 OTOH,它具有能與您建立多個上下文,每個都有自己的mylist實例的可能的好處:

​​