Something better than locals () or dict (foo = foo) for exporting context to template engines

So, after a brief discussion about #python about why not using locals , I thought about what would be better without the repetitive nature (i.e. not DRY) of dict(foo=foo,bar=bar) (or that same thing using syntax literal ( {} )).

Ideally, PEP can be presented (or already exists) that reflects this proposal of harmony ecmacript . (I want to focus on the dry aspect that he conveys).

So, do you have any solutions? Should I Represent PEP?

+2
python django jinja2
source share
3 answers

My currently proposed solution for this is the following template. Please tell me if this is as bad as using locals() .

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

One caveat is that this may be a bit small with python3, because it will use the new style classes with immutable dictproxy , and I will need to see how it will interact with this template library. Works well with simple '{foo}'.format(**_Context.__dict__) .

This is a definite improvement over locals() , as it is fairly explicit, and it does not flow to other parts of the local area. However, it flows '__module__' and '__doc__' with old style classes and many other things with new style classes.

0
source share

Here is my solution. There may be better ways to structure this, but it works!

Customization (Python 2 and 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 

And then use it:

 class context(ContextDict): a = 1 b = 2 >>> context {'a': 1, 'b': 2} 
0
source share

And the metaclass / attrs solution option:

 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 

Indeed, this question just turned into my sandbox for playing with metaclasses

0
source share

All Articles