Last active
February 4, 2018 05:12
-
-
Save dhilst/722d803e1aedb34f7f211463649885cf to your computer and use it in GitHub Desktop.
playing with lazy class properties using jinja recursive templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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