草庐IT

【Web开发】Python实现Web图表功能(pyecharts,Flask)

爱看书的小沐 2023-03-28 原文
<font color=purple face=华文行楷 size="5">"柳丝榆荚自芳菲,不管桃飘与李飞;"

1、简介

A Python Echarts Plotting Library. Apache Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,pyecharts 诞生了。

2、Flask + pyecharts

如何在 Flask 中使用 pyecharts。

2.1 Flask 模板渲染

$ mkdir pyecharts-flask-demo $ cd pyecharts-flask-demo $ mkdir templates 将 pyecharts 模板,位于 pyecharts.render.templates 拷贝至刚新建的 templates 文件夹。

  • server.py
from flask import Flask from jinja2 import Environment, FileSystemLoader from pyecharts.globals import CurrentConfig from markupsafe import Markup # 关于 CurrentConfig,可参考 [基本使用-全局变量] CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates")) from pyecharts import options as opts from pyecharts.charts import Bar app = Flask(__name__, static_folder="templates") def bar_base() -> Bar: c = ( Bar() .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]) .add_yaxis("商家A", [5, 20, 36, 10, 75, 90]) .add_yaxis("商家B", [15, 25, 16, 55, 48, 8]) .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="爱看书的小沐")) ) return c @app.route("/") def index(): c = bar_base() return Markup(c.render_embed()) if __name__ == "__main__": app.run()

2.2 Flask 前后端分离

前后端分离可以使用动态更新数据,增量更新数据等功能。

新建一个 HTML 文件。 新建 HTML 文件保存位于项目根目录的 templates 文件夹,这里以如下 index.html 为例. 主要用到了 jquery 和 pyecharts 管理的 echarts.min.js 依赖。

  • index.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>动态更新数据</title> <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script> <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script> </head> <body> <div id="bar" style="width:1000px; height:600px;"></div> <script> ( function () { var result_json = '{{ result_json|tojson }}'; // var result = JSON.parse(result_json); var chart = echarts.init(document.getElementById('bar'), 'gray', {renderer: 'canvas'}); $.ajax({ type: "GET", url: "http://127.0.0.1:5000/barChart", dataType: 'json', data: {result: result_json}, success: function (result) { chart.setOption(result); } }); } ) </script> </body> </html>
  • app.py:
from random import randrange from flask import Flask, render_template from pyecharts import options as opts from pyecharts.charts import Bar app = Flask(__name__, static_folder="templates") def bar_base() -> Bar: c = ( Bar() .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]) .add_yaxis("商家A", [randrange(0, 100) for _ in range(6)]) .add_yaxis("商家B", [randrange(0, 100) for _ in range(6)]) .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副标题")) ) return c @app.route("/") def index(): return render_template("index.html") @app.route("/barChart") def get_bar_chart(): c = bar_base() return c.dump_options_with_quotes() if __name__ == "__main__": app.run()

2.3 定时全量更新图表

前端主动向后端进行数据刷新 定时刷新的核心在于 HTML 的 setInterval 方法。

  • index.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Awesome-pyecharts</title> <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script> <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script> </head> <body> <div id="bar" style="width:1000px; height:600px;"></div> <script> var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'}); $( function () { fetchData(chart); setInterval(fetchData, 2000); } ); function fetchData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/barChart", dataType: 'json', success: function (result) { chart.setOption(result); } }); } </script> </body> </html>
  • app.py: 代码同上。

2.4 定时增量更新图表

  • index.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Awesome-pyecharts</title> <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script> <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script> </head> <body> <div id="bar" style="width:1000px; height:600px;"></div> <script> var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'}); var old_data = []; $( function () { fetchData(chart); setInterval(getDynamicData, 2000); } ); function fetchData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/lineChart", dataType: "json", success: function (result) { chart.setOption(result); old_data = chart.getOption().series[0].data; } }); } function getDynamicData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/lineDynamicData", dataType: "json", success: function (result) { old_data.push([result.name, result.value]); chart.setOption({ series: [{data: old_data}] }); } }); } </script> </body> </html>
  • app.py:
from random import randrange from flask.json import jsonify from flask import Flask, render_template from pyecharts import options as opts from pyecharts.charts import Line app = Flask(__name__, static_folder="templates") def line_base() -> Line: line = ( Line() .add_xaxis(["{}".format(i) for i in range(10)]) .add_yaxis( series_name="", y_axis=[randrange(50, 80) for _ in range(10)], is_smooth=True, label_opts=opts.LabelOpts(is_show=False), ) .set_global_opts( title_opts=opts.TitleOpts(title="动态数据"), xaxis_opts=opts.AxisOpts(type_="value"), yaxis_opts=opts.AxisOpts(type_="value"), ) ) return line @app.route("/") def index(): return render_template("index.html") @app.route("/lineChart") def get_line_chart(): c = line_base() return c.dump_options_with_quotes() idx = 9 @app.route("/lineDynamicData") def update_line_data(): global idx idx = idx + 1 return jsonify({"name": idx, "value": randrange(50, 80)}) if __name__ == "__main__": app.run()

3、Flask + echarts.js

3.1 直接渲染

  • app.py:
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') if __name__ == '__main__': app.run(debug=True)
  • index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>第一个 ECharts 实例</title> <!-- 引入 echarts.js --> <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> </head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width: 600px;height:400px;"></div> <script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); // 指定图表的配置项和数据 var option = { legend: {}, tooltip: {}, dataset: { source: [ ['product', '2012', '2013', '2014', '2015'], ['Matcha Latte', 41.1, 30.4, 65.1, 53.3], ['Milk Tea', 86.5, 92.1, 85.7, 83.1], ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4] ] }, xAxis: [ {type: 'category', gridIndex: 0}, {type: 'category', gridIndex: 1} ], yAxis: [ {gridIndex: 0}, {gridIndex: 1} ], grid: [ {bottom: '55%'}, {top: '55%'} ], series: [ // 这几个系列会在第一个直角坐标系中,每个系列对应到 dataset 的每一行。 {type: 'bar', seriesLayoutBy: 'row'}, {type: 'bar', seriesLayoutBy: 'row'}, {type: 'bar', seriesLayoutBy: 'row'}, // 这几个系列会在第二个直角坐标系中,每个系列对应到 dataset 的每一列。 {type: 'bar', xAxisIndex: 1, yAxisIndex: 1}, {type: 'bar', xAxisIndex: 1, yAxisIndex: 1}, {type: 'bar', xAxisIndex: 1, yAxisIndex: 1}, {type: 'bar', xAxisIndex: 1, yAxisIndex: 1} ] } // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); </script> </body> </html>

3.2 模板渲染

例子: 模板

  • app.py:
import pandas as pd from flask import Flask, render_template datas = {} datas2 = {} df = pd.read_csv('data/datum_shift.csv') df = df.sort_values('AREA_SOUTH_BOUND_LAT', ascending=False) for item in df.head().values: datas[item[0]] = item[1] datas2[item[0]] = item[2] app = Flask(__name__) @app.route('/') def index(): return render_template('index.html', datas=datas) if __name__ == '__main__': app.run(debug=True)
  • index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>房源占比前五的饼图</title> <script src="./static/js/echarts.min.js"></script> </head> <body> <div id="main" style="width:1000px;height:400px"></div> <script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); option = { title: { text: 'datum_shift', subtext: '饼图练习', left: 'center' }, tooltip: { trigger: 'item' }, legend: { orient: 'vertical', left: 'left' }, series: [ { name: '各项占比', type: 'pie', radius: '50%', data: [ {% for data in datas %} {value:{{ datas[data] }}, name: '{{data}}'}, {% endfor %} ], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); </script> </body> </html>

3.3 异步请求$.ajax

例子:$.ajax

创建目录如下:

  • test_flask.py:
import json from flask import Flask, request, jsonify,render_template app = Flask(__name__) @app.route('/test') def hello_world(): return 'Hello World,爱看书的小沐!' @app.route("/") def index(): return render_template("index.html") @app.route('/getdata_bar') def getdata_bar(): language = ['python', 'java', 'c', 'c++', 'c#', 'php'] value = ['100', '150', '100', '90', '80', '90'] return json.dumps({'language':language,'value':value},ensure_ascii=False) @app.route('/getdata_pie') def getdata_pie(): data = [ {"value": 235, "name": '视频广告'}, {"value": 274, "name": '联盟广告'}, {"value": 310, "name": '邮件营销'}, {"value": 335, "name": '直接访问'}, {"value": 400, "name": '搜索引擎'}, {"value": 90, "name": '其他'}, ], return json.dumps({'data':data},ensure_ascii=False) if __name__ == '__main__': app.run(host="0.0.0.0", port=8080)
  • index.html:
<head> <meta charset="UTF-8"> <title>Echarts</title> <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script> <script src="/static/js/echarts.min.js"></script> <style> body { margin: 100px; } .flex-div{ display: flex; width: auto; } </style> </head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div class="flex-div"> <div id="echarts_lang" style="width: 600px;height:400px;"></div> <div id="echarts_ad" style="width: 600px;height:400px;"></div> <script type="text/javascript"> $(function () { // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts_lang')); $.ajax({ url:'/getdata_bar', success:function (data) { json_data=JSON.parse(data) console.info(json_data['language']) console.info(json_data['value']) var option = { title: { text: '人数统计' }, tooltip: {}, legend: { data:['2022年销量'] }, xAxis: { data: json_data['language'] }, yAxis: {}, series: [{ name: '2022年销量', type: 'bar', data: json_data['value'] }] }; myChart.setOption(option); } }) }) $(function () { // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echarts_ad')); $.ajax({ url:'/getdata_pie', success:function (data) { json_data=JSON.parse(data) console.info(json_data['data']) option = { series : [ { name: '访问来源', type: 'pie', radius: '55%', data: json_data['data'][0], roseType: 'angle', itemStyle: { normal: { shadowBlur: 200, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ], }; console.info(option) myChart.setOption(option); } }) }) </script> </body>

3.4 异步请求$.get

例子2: $.get

  • app.py:
from flask import Flask, request, jsonify,render_template app = Flask(__name__) categories=["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] data=[5, 20, 36, 10, 10, 20] data2=[111, 222, 80, 150, 75, 55] app = Flask (__name__) @app.route('/test') def hello_world(): return 'Hello World,爱看书的小沐!' @app.route('/', methods=["GET"]) def index(): return render_template("index.html") @app.route('/echarts', methods=["GET"]) def echarts(): return jsonify(categories = categories,data = data, data2 = data2) if __name__ == '__main__': app.run(host="0.0.0.0", port=8080)
  • index.html:
<!DOCTYPE html> <html style="height: 100%" lang="en"> <head> <meta charset="utf-8"> <title>My Finance</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script> <script src="https://cdn.staticfile.org/echarts/4.8.0/echarts.min.js"></script> <!-- 引入 vintage 主题 --> </head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width:1000px;height:300px;"></div> <script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); myChart.setOption({ title: { text: '$.get异步数据加载示例(爱看书的小沐)' }, tooltip: {}, legend: { data: ['1月销量', '2月销量'] }, xAxis: { data: [] }, yAxis: {}, series: [{ name: '1月销量', type: 'bar', data: [] },{ name: '2月销量', type: 'bar', data: [] }] }); // 异步加载数据 $.get('/echarts').done(function (data) { // 填入数据 myChart.setOption({ xAxis: { data: data.categories }, axisLabel: { show: true, interval: 0, rotate: 40, textStyle: { color: '#333' } }, series: [ { name: '1月销量', data: data.data }, { name: '2月销量', data: data.data2 } ] }); }); myChart.setOption(option); </script> </body> </html>

3.5 Flask + nodejs + vue

对于 Vue 3,你应该使用 npm 上可用的 Vue CLI v4.5 作为 @vue/cli。要升级,你应该需要全局重新安装最新版本的 @vue/cli:

# 全局安装 vue-cli yarn global add @vue/cli # 或 cnpm install -g @vue/cli

安装完后查看版本:

$ vue --version

然后在 Vue 项目中运行:

vue upgrade --next vue create、vue ui、vue init三种方式创建Vue项目。

vue create命令是vue-cli3.x提供创建Vue项目的方式,模板是固定的,模板选项可自由配置。 vue ui命令也是vue-cli3.x提供创建Vue项目的方式,可以通过操作可视化页面来创建和管理Vue项目。 vue init命令是vue-cli2.x提供创建Vue项目的方式,可以使用github上面的一些模板来初始化项目。比如webpack就是官方推荐的标准模板。

创建项目:

vue init webpack vue3-test

cd vue3-test npm run dev 访问网址:http://localhost:8080

npm install --save echarts vue-jsonp vue-resource

  • D:\0627\vue3-test\src\main.js:
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App.vue' import VueResource from 'vue-resource' import * as VueJsonp from 'vue-jsonp' // import echarts from 'echarts' import * as echarts from 'echarts'; Vue.use(VueJsonp) Vue.use(VueResource) Vue.prototype.$echarts = echarts new Vue({ el: '#app', render: h => h(App) })
  • D:\0627\vue3-test\src\App.vue:
<template> <div class="main"> <chart1 /> </div> </template> <script> import chart1 from "./components/chart1.vue"; export default { components: { chart1, }, }; </script>
  • D:\0627\vue3-test\src\components\chart1.vue:
<template> <div> <div id="echartContainer" style="width: 100%; height: 500px"></div> </div> </template> <script> export default { name: "chart1", data() { return {}; }, methods: { draw() { var myChart = this.$echarts.init( document.getElementById("echartContainer"), "infographic" ); myChart.setOption({ xAxis: {}, yAxis: {}, series: [ { symbolSize: 5, data: [], type: "bar", }, ], }); this.$http .get("http://localhost:5000/api/demo/", { headers: { "Access-Control-Allow-Origin": "*" }, }) .then((res) => { console.log(res.data); myChart.hideLoading(); myChart.setOption({ series: [{ data: res.data.product }] }); }); }, }, mounted() { this.draw(); }, }; </script> <style></style>
  • test_flask:
from flask import Flask, jsonify, render_template from flask.helpers import make_response from flask_cors import CORS app = Flask(__name__, static_folder='./dist', #设置静态文件夹目录 template_folder = "./dist", static_url_path="") #设置vue编译输出目录dist文件夹,为Flask模板文件目录 CORS(app, resources=r'/*') @app.route('/', methods=["GET"]) def index(): return render_template("index.html") @app.route('/api/demo/') def api_test(): ans = jsonify({ "product": [5, 20, 36, 10, 10, 20] }) return make_response(ans) if __name__ == '__main__': app.run(debug=True)

cd vue3-test npm run build npm run dev 访问:http://localhost:8080/ 以上是开启了两个web服务器(Flask、nodejs). 以下是开一个web服务器(Flask)的方法: 将上面打包的dist文件复制到Flask的主文件夹里,然后运行test_flask.py如下。

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭ 如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O??? 如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡) 感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

<font color=purple face=华文行楷 size="5">"侬今葬花人笑痴,他年葬侬知是谁?"

有关【Web开发】Python实现Web图表功能(pyecharts,Flask)的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  5. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  6. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  7. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  8. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  9. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐