Python 如何设计插件架构,让插件填充网页的不同部分?
我正试图设计一个插件系统来填充网页的不同组件,每个插件负责其自身的视图或底层数据的可视化(可以是股票数据,例如1000只股票)。 我需要帮助想出一个简单的设计,但正确地分离MVC组件。我觉得我目前的设计在整个html中不正确地混合,并且很难改变main index.html页面的整体布局我不知道如何在保持代码简单和精简的同时解决这个问题,同时允许每个插件在页面的某个部分上具有最大的灵活性。 做这件事的最佳实践想法/库是什么? 我的一个想法是生成由预定义的javascript/html小部件使用的json是否有python库为此提供了体系结构(可能还有一些用于数据表示的不错的小部件)? 为了提供一些背景信息,这些插件将成为一个应用程序的一部分,该应用程序为科学家提供了一种简单的基于网络的方式,以查看数据分析管道的结果。 管道生成1到1000个目录(每个实验样本一个),每个目录包含5到20个标准和自定义文件类型。我的python应用程序对这些目录进行爬网,并生成一个网页,在该网页中,可以在所有示例中查看每种类型的结果(以某种摘要格式,或通过翻转/滚动示例) [1] 谢谢 -本 另外,我当前的伪代码是:Python 如何设计插件架构,让插件填充网页的不同部分?,python,design-patterns,Python,Design Patterns,我正试图设计一个插件系统来填充网页的不同组件,每个插件负责其自身的视图或底层数据的可视化(可以是股票数据,例如1000只股票)。 我需要帮助想出一个简单的设计,但正确地分离MVC组件。我觉得我目前的设计在整个html中不正确地混合,并且很难改变main index.html页面的整体布局我不知道如何在保持代码简单和精简的同时解决这个问题,同时允许每个插件在页面的某个部分上具有最大的灵活性。 做这件事的最佳实践想法/库是什么? 我的一个想法是生成由预定义的javascript/html小部件使用的
plugin_registry = []
class FileTypeHandlerPlugin:
__metaclass__ = register_plugin # based on effbot.org post [1]
# Base class's methods won't contain code. Just included for explanation.
def handle_files(self, all_file_paths):
# 1. pick out the files of your type
# 2. parse the files and create data structure to use by get_html(..)
# 3. maybe generate some files and summary graphs (eg. summary_graph.png)
def get_html(self):
# get the html
result = """
<img src="summary_graph.png">
<table>
<tr><td>sample</td><td>value1</td><td>value2...
<tr><td>s1 ...
</table>
"""
return result
def get_heading(self):
return "some heading"
class FileType1Handler(FileTypeHandlerPlugin):
def get_html(self)
return "<pre>%s</pre>" % self.quality_string....
def get_heading(self):
return "Quality Scores"
def handle_files(self, all_file_paths):
self.quality_score_files = [p for p in all_file_paths if p.endswith(".qual")]
...
def main():
all_file_paths = []
for dirpath, dirnames, filenames in os.walk("."):
all_file_paths.extend(filenames)
for plugin in plugin_registry:
plugin.handle_files(all_file_paths)
f = open("index.html", "w")
for plugin in plugin_registry:
f.write( "<h3>" + plugin.get_heading() + "</h3>")
f.write( plugin.get_html() )
f.close()
webserver.start()
plugin\u注册表=[]
类FileTypeHandlerPlugin:
__元类=注册插件#基于effbot.org帖子[1]
#基类的方法不包含代码。只是为了解释。
def句柄文件(自身、所有文件路径):
# 1. 挑选你喜欢的文件
# 2. 解析文件并创建数据结构以供get_html(..)使用
# 3. 可能会生成一些文件和摘要图(例如summary_graph.png)
def get_html(自我):
#获取html
结果=”“”
samplevalue1value2。。。
s1。。。
"""
返回结果
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
def get_标题(自身):
返回“某个标题”
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
类FileType1Handler(FileTypeHandlerPlugin):
def get_html(自我)
返回“%s”%self.quality\u字符串。。。。
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
def get_标题(自身):
返回“质量分数”
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
def句柄文件(自身、所有文件路径):
self.quality_score_files=[p表示所有_file_路径中的p,如果p.endswith(“.qual”)]
...
def main():
所有_文件_路径=[]
对于os.walk(“.”)中的dirpath、dirname和文件名:
所有文件路径。扩展(文件名)
对于plugin_注册表中的插件:
plugin.handle_文件(所有_文件路径)
f=打开(“index.html”、“w”)
对于plugin_注册表中的插件:
f、 写入(“+插件。获取标题()+”)
f、 写入(plugin.get_html())
f、 关闭()
webserver.start()
在框架中设计一个插件接口,由插件web应用程序实现。通过依赖注入,您可以在运行时加载插件web应用程序,并验证插件是否正确实现了接口。因此,将在运行时加载正确的插件。在经典范例中看到这一点可能会有所帮助
- 您的模型应该从文件中检索数据
- 您的视图应该以他们认为合适的方式装饰数据
- 您的控制器应该将视图与正确的模型链接起来,并处理诸如用户输入之类的内容
class CSVHandler():
#一个视图插件,可以输出HTML。
def句柄(数据):
输出=“”
对于文件输入数据:
如果data.type!='csv':
持续
#把东西做成输出
返回输出
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
查看插件=[]
def寄存器\视图\插件(插件):
查看插件。附加(插件)
注册\查看\插件(SummaryHandler())
注册\查看\插件(CSVHandler())
注册\查看\插件(PDFHandler())
def渲染(数据):
输出='\n'.join([x.handle(数据)用于视图中的x\u插件])
@app.route(“/show/”)
def显示(样本id):
#这是控制器
数据=获取数据(样本id)
返回渲染(数据)
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
def get_数据(样本id):
#返回数据的模型。
返回[{'type':'csv','content':'…'},
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
{'type':'pdf','author':'Foo','content':'…'}]
谢谢您的回复。对于句柄(..)方法应该返回什么(html?javascript?)以及呈现(..)应该如何将其转换为最终的html页面,您有什么建议吗?是否有python库提供用于生成html或javascript组件的数据结构或方法?
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]