Я пишу препроцессор на Python, часть которого работает с AST.
Существует метод render()
который выполняет преобразование различных операторов в исходный код.
Теперь у меня это так (сокращенно):
def render(self, s):
""" Render a statement by type. """
# code block (used in structures)
if isinstance(s, S_Block):
# delegate to private method that does the work
return self._render_block(s)
# empty statement
if isinstance(s, S_Empty):
return self._render_empty(s)
# a function declaration
if isinstance(s, S_Function):
return self._render_function(s)
# ...
Как видите, он утомителен, подвержен ошибкам, а код довольно длинный (у меня есть еще много видов утверждений).
Идеальным решением было бы (в синтаксисе Java):
String render(S_Block s)
{
// render block
}
String render(S_Empty s)
{
// render empty statement
}
String render(S_Function s)
{
// render function statement
}
// ...
Конечно, Python не может этого сделать, потому что он имеет динамическую типизацию. Когда я искал способ имитации перегрузки метода, все ответы просто говорили: "Вы не хотите делать это в python". Я полагаю, что в некоторых случаях это так, но здесь kwargs
действительно бесполезен.
Как бы я сделал это в Python, без отвратительной последовательности длиной в километр, если проверка типов, если, как показано выше? Кроме того, предпочтительно "питонический" способ сделать это?
Примечание. Может быть несколько реализаций "Renderer", которые представляют операторы по-разному. Поэтому я не могу переместить код рендеринга в операторы и просто вызвать s.render()
. Это должно быть сделано в классе визуализации.
(Я нашел какой-то интересный код "посетителя", но я не уверен, действительно ли это то, что я хочу).