Если вы хотите сгенерировать код, используйте что-то вроде mako или jinja .Вы хотите сохранить генерацию своего кода и фактический код, который ваша программа работает отдельно.Это происходит главным образом потому, что код, сгенерированный в python, намного более расстраивает отладку.
Например, в Python вы можете сгенерировать ваш код следующим образом:
from textwrap import dedent
class Logger:
for level in ('debug', 'info'):
exec(dedent("""
@staticmethod
def {level}(text):
log.log(text, {level!r})
""".format(level=level)))
Logger.info('test')
Но тогда в исключении ваш стектрассировка будет сбивать с толку, например.
Traceback (most recent call last):
File "C:\Users\User\Documents\python\a.py", line 18, in <module>
Logger.info('test')
File "<string>", line 4, in info <-- what is <string> and where can you find it?
NameError: name 'log' is not defined
Вместо этого вы можете попробовать:
class Logger:
def gen_log_func(level):
def _log(text):
log.log(text, level)
_log.__name__ = level
return _log
for level in ('debug', 'info'):
locals()[level] = staticmethod(gen_log_func(level))
del gen_log_func
Logger.info('test')
Лучше, но этот подоконник выглядит довольно грязно.Дальнейшие линтеры все еще не могут помочь вам с опечатками в именах функций и атрибутов.Все, что знает Линтер, Logger.info
- это такая же опечатка, как и Logger.inf
.
С помощью mako вы можете написать файл шаблона следующим образом:
<%
levels = 'debug', 'info'
%>
class Logger:
% for level in levels:
@staticmethod
def ${level}(text):
log.log(text, ${repr(level)})
% endfor
Здесь уродствошаблона захвачен внутри файла шаблона, и сгенерированный код выглядит просто как обычный, полностью выраженный код.