我为数据分析项目编写了代码,但它变得笨拙,我想找到一种更好的结构化方法,以便我可以与其他人分享。
为了简洁起见,我有以下内容:
def process_raw_text(txt_file):
# do stuff
return token_text
def tag_text(token_text):
# do stuff
return tagged
def bio_tag(tagged):
# do stuff
return bio_tagged
def restructure(bio_tagged):
# do stuff
return(restructured)
print(restructured)
基本上我希望程序按顺序运行所有函数并打印输出。
在研究如何构建这个时,我会阅读以下类:
class Calculator():
def add(x, y):
return x + y
def subtract(x, y):
return x - y
在构建项目以允许单独调用单个函数时,这似乎很有用,例如add
函数与Calculator.add(x,y)
,但我不确定这是我想要的。
我是否应该研究一系列连续的函数(用于构造数据流并提供可读性)?理想情况下,我希望所有函数都在“我可以调用一次”的内容中,然后运行其中的所有内容。
答案 0 :(得分:2)
将每个函数的输出链接在一起作为下一个的输入:
def main():
print restructure(bio_tag(tag_text(process_raw_text(txt_file))
if __name__ == '__main__':
main()
@SvenMarnach提出了一个很好的建议。更通用的解决方案是认识到重复使用输出作为序列中下一个输入的这种想法正是reduce
函数的作用。我们想从一些输入txt_file
:
def main():
pipeline = [process_raw_text, tag_text, bio_tag, restructure]
print reduce(apply, pipeline, txt_file)
答案 1 :(得分:1)
只需使用模块和函数即可实现简单的动态管道。
my_module.py
def 01_process_raw_text(txt_file):
# do stuff
return token_text
def 02_tag_text(token_text):
# do stuff
return tagged
my_runner.py
import my_module
if __name__ == '__main__':
funcs = sorted([x in my_module.__dict__.iterkeys() if re.match('\d*.*', x)])
data = initial_data
for f in funcs:
data = my_module.__dict__[f](data)
答案 2 :(得分:1)
没有什么可以阻止您创建一个类(或一组类)来表示您想要使用将在序列中调用所需函数的实现进行管理。
class DataAnalyzer():
# ...
def your_method(self, **kwargs):
# call sequentially, or use the 'magic' proposed by others
# but internally to your class and not visible to clients
pass
函数本身可以在模块中保持私有,这似乎是实现细节。