Skip to content

Instantly share code, notes, and snippets.

@dhilst
Last active February 4, 2018 05:12
Show Gist options
  • Save dhilst/722d803e1aedb34f7f211463649885cf to your computer and use it in GitHub Desktop.
Save dhilst/722d803e1aedb34f7f211463649885cf to your computer and use it in GitHub Desktop.
playing with lazy class properties using jinja recursive templates
from jinja2 import Template
from jinja2.runtime import Context
def merge_vars(obj):
d = {}
for o in reversed(obj.mro()):
d.update(vars(o))
return d
class TemplateProperty(Template):
def __get__(self, obj, cls):
class MyContext(Context):
def resolve(self, key):
v = super().resolve(key)
if isinstance(v, (TemplateProperty,)):
return v.render(**merge_vars(cls))
return v
self.environment.context_class = MyContext
return self.render(**merge_vars(cls))
def __set__(self, obj, value):
raise AttributeError()
class Base:
first_name = 'Daniel'
last_name = 'Hilst'
full_name = TemplateProperty('{{first_name}} {{last_name}}')
reversed_full_name_cap = TemplateProperty('{{full_name[::-1].capitalize()}}')
class Child(Base):
last_name = 'Selli'
upper_name = TemplateProperty('{{full_name.upper()}}')
class Grandson(Child):
lower_name = TemplateProperty('{{full_name.lower()}}')
missing = TemplateProperty('{{undefined_property}}')
print(Base.full_name) # Daniel Hilst
print(Base.reversed_full_name_cap) # Tslih leinad
print(Child.full_name) # Daniel Selli
print(Child.upper_name) # DANIEL SELLI
print(Grandson.lower_name) # daniel selli
print(Grandson.missing)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment