我有一个带有几个辅助函数的函数。这是相当普遍的情况。我想将它们分组在一个共同的上下文中以便于阅读,我想知道如何正确地做到这一点。
简化示例:
def create_filled_template_in_temp(path, values_mapping):
template_text = path.read_text()
filled_template = _fill_template(template_text, values_mapping)
result_path = _save_in_temp(filled_template)
return result_path
def _fill_template(template_text, values_mapping):
...
def _save_in_temp(filled_template):
_, pathname = tempfile.mkstemp(suffix='.ini', text=True)
path = pathlib.Path(pathname)
path.write_text(text)
return path
...
create_filled_template_in_temp(path, values_mapping)
请注意,我不需要模块级别的辅助方法,因为它们只属于一种方法。想象一下,在同一模块中有如上所述的几个这样的例子。模块级别的Maany非公共功能。一团糟(这种情况多次发生)。另外,我想给它们上下文并使用上下文的名称来简化内部命名。
解决方案#0:模块
把它放在另一个模块中:
template_fillers.create_in_temp(path, values_mapping)
问题:
最后,这只是为它添加模块的代码太少了。
解决方案#1:课程
创建一个没有__init__
且只有一个公共(通过命名约定)方法的类:
class TemplateFillerIntoTemp:
def run(self, path, values_mapping):
template_text = path.read_text()
filled_template = self._fill_template(template_text, values_mapping)
result_path = self._save_in_temp(filled_template)
return result_path
def _fill_template(self, template_text, values_mapping):
...
def _save_in_temp(self, filled_template):
_, pathname = tempfile.mkstemp(suffix='.ini', text=True)
path = pathlib.Path(pathname)
path.write_text(text)
return path
...
TemplateFillerIntoTemp().run(path, values_mapping)
这是我过去多次做过的事。问题:
解决方案#2:静态类
采取解决方案#1,在任何地方添加@staticmethod
。也可能是ABC元类。
TemplateFillerIntoTemp.run(path, values_mapping)
Pro:有一个明确的迹象表明这一切都与实例无关。 Con:还有更多代码。
解决方案#3:带__call __
的班级使用解决方案#1,使用main方法创建一个__call__
函数,然后在模块级别创建一个名为create_filled_template_in_temp
的实例。
create_filled_template_in_temp(path, values_mapping)
Pro:调用就像一个函数。骗局:实施过度,不适合此目的。
解决方案#4:将辅助函数插入主函数
将它们添加到内部。
def create_filled_template_in_temp(path, values_mapping):
def _fill_template(template_text, values_mapping):
...
def _save_in_temp(filled_template):
_, pathname = tempfile.mkstemp(suffix='.ini', text=True)
path = pathlib.Path(pathname)
path.write_text(text)
return path
template_text = path.read_text()
filled_template = _fill_template(template_text, values_mapping)
result_path = _save_in_temp(filled_template)
return result_path
...
create_filled_template_in_temp(path, values_mapping)
Pro:如果行总数很少且辅助函数很少,这看起来很好。骗局:否则没有。
答案 0 :(得分:11)
#4的修改:创建内部函数,并且函数体也是内部函数。这具有仍然从上到下阅读的良好特性,而不是将身体一直放在底部。
def create_filled_template_in_temp(path, values_mapping):
def body():
template_text = path.read_text()
filled_template = fill_template(template_text, values_mapping)
result_path = save_in_temp(filled_template)
return result_path
def fill_template(template_text, values_mapping):
...
def save_in_temp(filled_template):
_, pathname = tempfile.mkstemp(suffix='.ini', text=True)
path = pathlib.Path(pathname)
path.write_text(text)
return path
return body()
(我不关心领先的下划线,所以他们没有生存。)