2013-02-21 76 views
2

因此,在簡單討論關於why not to use locals的#python之後,我在思考什麼是沒有重複性質的更好方法非DRY)的dict(foo=foo,bar=bar)(或使用文字語法({}))相同)。比當地人()或字典(foo = foo)更好的將上下文導出到模板引擎

理想情況下,可以提交反映this ecmascript harmony proposal的PEP(或已存在的PEP)。 (我想強調它傳達的DRY方面)。

那麼,你有任何解決方案嗎?我應該提交一份PEP嗎?

+0

好問題 - 雖然,不適合堆棧溢出,因爲這是真的是一個討論的邀請。這在Python郵件列表上會更好。 – 2013-02-22 03:37:40

+0

而且,我更願意放棄 - 這裏是關於可用[Python郵件列表](http://python.org/community/lists/)的信息。 – 2013-02-22 03:47:24

+0

是的,就Web內容而言,SO只是更容易訪問 - 當搜索結果出現時,您不必摸索檔案就能找到答案。謝謝,我一定會在郵件列表上提問。 – forivall 2013-02-22 06:50:42

回答

0

我目前提出的解決方案是以下模式。請告訴我,這是否與使用locals()時一樣糟糕。

class _Context: 
    foo = 'bar' 
render(request, 'example.html', vars(_Context)) 

一個需要注意的是,這可能與python3有點玄乎,因爲它會使用新的樣式類與不變dictproxy,而我需要看看它是如何與給定的模板庫進行交互。使用簡單的'{foo}'.format(**_Context.__dict__)可以很好地工作。

明顯改善了locals(),因爲它非常明確,並且不會泄漏本地範圍的其他部分。然而,它確實泄漏了'__module__''__doc__'舊風格的類和一些其他的東西與新風格的類。

+0

這個或'__dict__'很好!被問到比我更pythonic的人。 – forivall 2015-09-13 02:00:07

0

這是我的解決方案。有可能有更好的方法來構建這個,但它的工作原理!

設置(Python 2和3):

class ContextDictBase(type): 
    @staticmethod 
    def __newnew(cls, name, bases, attrs): 
     attrs.pop('__module__', None) 
     return attrs 
    def __new__(cls, name, bases, attrs): 
     ContextDictBase.__new__ = staticmethod(ContextDictBase.__newnew) 
     return super(ContextDictBase, cls).__new__(cls, name, bases, attrs) 

的Python 2:

class ContextDict(object): 
    __metaclass__ = ContextDictBase 

的Python 3:

class ContextDict(object, metaclass=ContextDictBase): 
    pass 

然後使用它:

class context(ContextDict): 
    a = 1 
    b = 2 

>>> context 
{'a': 1, 'b': 2} 
0

而且在元類/ ATTRS解決方案的變化:

def make_dict(name, bases, attrs): 
    attrs.pop('__module__') 
    attrs.pop('__metaclass__', None) # not needed in python3 
    return attrs 

的Python 2:

class Context: 
    __metaclass__ = make_dict 

的Python 3:

class Context(metaclass=make_dict): 
    a = 1 
    b = 2 

真的,這個問題纔剛剛變成了我的沙箱玩metaclasses

相關問題