2013-01-09 27 views
1

我在寫一些我想調用的函數。他們被稱爲一個往往不會改變的背景和一些數據。在上下文中花費大量時間來完成,但一旦完成,使用它的數據是相當輕量級的。我可以使用(誤用)globals()命名空間來存儲持久性嗎?

這顯然也映射到以下模式

class MyFunc(): 
    def __init__(self, context): 
     self.foo_d_context=foo(context) 
    def __call__(self, data): 
     return bar(self.foo_d_context, data) 

if __name__ == '__main__': 
    my_callable=MyFunc(my_context) 

    results1=my_callable(my_data1) 
    results2=my_callable(my_data2) 

然而,我的用戶反對初始創建的my_callable對象。什麼會更容易接受他們的是,可以像使用的功能...

結果= my_func,並將(my_context,my_data)

...和具備的功能my_func,並將看看從以前的presistent數據呼叫存在,並且與上次呼叫相同。

這個問題是第一次調用該函數,它可以在哪裏存儲持久性數據?似乎Python標準庫中已有的幾個實用程序表示它們是這樣工作的,並且文檔討論了設置該對象的輔助函數。但我還沒有弄清楚它是如何工作的。

我可以想出一個辦法,但它感覺不對,不寬鬆。看起來我可以直接將對象放入globals()命名空間,並且可以在任何函數中執行此操作。所以,我可以做

def my_func(context,data): 
    glob=globals() 
    try: 
     if glob['__my_persistent_reference_context_$$$'] == context: 
      return bar(glob['__my_foo_d_context_$$$'],data) 
    except KeyError: 
     pass 
    glob['__my_foo_d_context_$$$']=foo(context) 
    glob['__my_persistent_reference_context_$$$'] = context 
    return bar(glob['__my_foo_d_context_$$$'],data) 

已經寫在上面,它發生,我認爲這個功能可以創建MYFUNC類,這聽起來更接近我正在尋找概念的一個對象,但它仍然有來電它的東西,把它放在某個地方,這樣就不能解決基本的'我可以使用全局名稱空間嗎?'問題。

可以嗎?

它會一直工作嗎? (我使用的是2.6.6,它最終還能在3下工作嗎?)

有沒有更好的方法呢?

有更好的命名空間污染嗎?

我是否應該堅持這樣做的課程方式是正確的?

+4

我認爲你濫用術語「持久性」;它幾乎從來沒有用於指代內存中的某些東西。 – geoffspear

+0

另外,可讀性很重要 - 我還沒有很好地理解你想要做的事情,我敢肯定有可能比任何一種方法都更好,但第二個例子是一堆難以理解的混亂。 –

回答

2

從你在說什麼,我認爲你想要做的就是緩存一個值。這可以通過使用不影響其他名稱空間的函數屬性很容易地完成。

def my_func(context, data): 
    try: 
     reference, saved = my_func.cache 
    except AttributeError: 
     reference, saved = None, None 
    computed = saved if reference == context else foo(context) 
    my_func.cache = context, computed 
    return bar(computed, data) 
+0

功能屬性 - 它們從哪裏來?我必須更有效地學習RTFM,但它太糟糕了。我正在誤解當函數退出時關於函數的所有內容都被蒸發了,所以你需要將永久(永久)(即不蒸發)存儲附加到對象或命名空間。不過,現在我提醒說,函數本身是一個對象,存在於導入的模塊名稱空間中,因此使用屬性非常有用。非常感謝你 –

0

確定您可以將任何內容放入globals()中,如果您在密鑰中使用無效的字符作爲標識符,將無法以「正常」方式訪問該字符。但讓我們一步一步來。如果你要使用字典,爲什麼不使用自己的你甚至不需要在任何使用它的函數中聲明它是全局的。

_my_global_state = {} 

def foo(x): 
    _my_global_state.setdefault("counter", 0) 
    _my_global_state["counter"] += x 

依此類推。

但屬性語法是更好,所以讓我們用一個對象實例:

_my_global_state = object() 

def foo(x): 
    if hasattr(_my_global_state, "counter"): 
     _my_global_state.counter += x 
    else: 
     _my_global_state.counter = x 

當然,在作出這一飛躍,現在你還不如把數據和功能彙集成一個單一的...啄。這是真正的解決方案。使用類來保存您的數據以及對其進行操作的功能。

相關問題