使用外部 conf 文件配置 pygal 图表?
Configure a pygal chart with an external conf file?
我正在使用 pygal 在我正在开发的 Web 应用程序中绘制一些数据图表,我认为将图表的配置外部化是个好主意。
所以我在我的 conf 文件中写了一个部分来复制我的代码 conf:
[ChartOptions]
x_label_rotation: -75
x_labels_major_every: 5
show_minor_x_labels: False
range: (30,100)
stroke_style: {'width':8}
title: Chart Title
并发现将 ChartOptions 部分传递给(例如)pygal.Config() 导致
File "/usr/local/lib/python2.7/dist-packages/pygal/util.py", line 370, in mergextend
if list1 is None or _ellipsis not in list1:
我该怎么做?
我在 Python 还很陌生,所以也许这一切都是不必要的,众所周知,或者存在更好的方法。我遇到了很多麻烦,找不到任何东西,所以我们来了。
我发现的第一件事是 pygal.util.mergextend() 不喜欢在需要其他数据类型的地方查找字符串。 ConfigParser.read()._sections[your_section_here] 返回的 OrderedDict 中的值都是字符串,因此需要将它们转换为正确的类型。
输入:ast.literal_eval()。
这似乎可行,但一直在 __name__
值上引发 ValueError('malformed string '),这是一个 str,每个类型(options['__name__
' ]).那么,现在呢?
我真的不需要 __name__
值,所以我使用 pop()
将其从字典中删除,剩下处理 title
值。我想使用 title
,知道每个 pygal 可以是一个字符串并且可以控制它的值,那么可以做什么呢?
ast.literal_eval()
的文档坚持它允许字符串,因此在 conf 文件中向 title
值添加引号似乎 'reasonable',并且有效。
将所有这些放在一起,并向混合物中加入烧瓶,我们得到:
配置文件:
...
[ChartOptions]
x_label_rotation: -75
x_labels_major_every: 5
show_minor_x_labels: False
range: (30,100)
stroke_style: {'width':8}
# note added quotes below
title: "Chart Title"
...
app.py:
import ConfigParser
import ast
import pygal
from pygal import Config
from flask import Flask, render_template
...
config = ConfigParser.ConfigParser()
config.read('my.conf')
chart_options = config._sections[CHART_SECTION]
chart_options.pop('__name__')
for key in chart_options.keys():
chart_options[key] = ast.literal_eval(chart_options[key])
@app.route('/route')
def a_route():
global chart_options # haven't made this into a class yet...
chart_config = Config(**chart_options)
chart = pygal.Line(chart_config)
...
# add data and finalize chart setup
...
return render_template('route.html', chart=chart.render())
...
我正在使用 pygal 在我正在开发的 Web 应用程序中绘制一些数据图表,我认为将图表的配置外部化是个好主意。
所以我在我的 conf 文件中写了一个部分来复制我的代码 conf:
[ChartOptions]
x_label_rotation: -75
x_labels_major_every: 5
show_minor_x_labels: False
range: (30,100)
stroke_style: {'width':8}
title: Chart Title
并发现将 ChartOptions 部分传递给(例如)pygal.Config() 导致
File "/usr/local/lib/python2.7/dist-packages/pygal/util.py", line 370, in mergextend
if list1 is None or _ellipsis not in list1:
我该怎么做?
我在 Python 还很陌生,所以也许这一切都是不必要的,众所周知,或者存在更好的方法。我遇到了很多麻烦,找不到任何东西,所以我们来了。
我发现的第一件事是 pygal.util.mergextend() 不喜欢在需要其他数据类型的地方查找字符串。 ConfigParser.read()._sections[your_section_here] 返回的 OrderedDict 中的值都是字符串,因此需要将它们转换为正确的类型。
输入:ast.literal_eval()。
这似乎可行,但一直在 __name__
值上引发 ValueError('malformed string '),这是一个 str,每个类型(options['__name__
' ]).那么,现在呢?
我真的不需要 __name__
值,所以我使用 pop()
将其从字典中删除,剩下处理 title
值。我想使用 title
,知道每个 pygal 可以是一个字符串并且可以控制它的值,那么可以做什么呢?
ast.literal_eval()
的文档坚持它允许字符串,因此在 conf 文件中向 title
值添加引号似乎 'reasonable',并且有效。
将所有这些放在一起,并向混合物中加入烧瓶,我们得到:
配置文件:
...
[ChartOptions]
x_label_rotation: -75
x_labels_major_every: 5
show_minor_x_labels: False
range: (30,100)
stroke_style: {'width':8}
# note added quotes below
title: "Chart Title"
...
app.py:
import ConfigParser
import ast
import pygal
from pygal import Config
from flask import Flask, render_template
...
config = ConfigParser.ConfigParser()
config.read('my.conf')
chart_options = config._sections[CHART_SECTION]
chart_options.pop('__name__')
for key in chart_options.keys():
chart_options[key] = ast.literal_eval(chart_options[key])
@app.route('/route')
def a_route():
global chart_options # haven't made this into a class yet...
chart_config = Config(**chart_options)
chart = pygal.Line(chart_config)
...
# add data and finalize chart setup
...
return render_template('route.html', chart=chart.render())
...