所以,在对#python关于why not to use locals的简短讨论之后,我正在思考如果没有dict(foo=foo,bar=bar)
的重复性质(即不是DRY)会有什么更好的方式(或者使用文字语法({}
))。
理想情况下,可以提交镜像this ecmascript harmony proposal的PEP(或已经存在的PEP)。 (我想强调它传达的DRY方面)。
那么,你有什么解决方案吗?我应该提交PEP吗?
答案 0 :(得分:0)
我目前提出的解决方案是以下模式。请告诉我这是否与使用locals()
一样糟糕。
class _Context:
foo = 'bar'
render(request, 'example.html', vars(_Context))
有一点需要注意的是,使用python3可能会有点不确定,因为它会使用带有不可变dictproxy
的新式类,我需要看看它如何与给定的模板库进行交互。使用简单的'{foo}'.format(**_Context.__dict__)
工作正常。
是对locals()
的明显改进,因为它相当明确,并且不泄漏本地范围的其他部分。但是,它确实会泄漏'__module__'
和'__doc__'
旧样式类以及其他一些新类型的东西。
答案 1 :(得分: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}
答案 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
真的,这个问题刚刚变成了我的沙盒,用于播放元类