Hadoop中的Python框架的使用指南

最近,我加入了Cloudera,在这之前,我在计算生物学/基因组学上已经工作了差不多10年。我的分析工作主要是利用Python语言和它很棒的科学计算栈来进行的。但Apache Hadoop的生态系统大部分都是用Java来实现的,也是为Java准备的,这让我很恼火。所以,我的头等大事变成了寻找一些Python可以用的Hadoop框架。

在这篇文章里,我会把我个人对这些框架的一些无关科学的看法写下来,这些框架包括:

  • Hadoop流
  • mrjob
  • dumbo
  • hadoopy
  • pydoop
  • 其它

最终,在我的看来,Hadoop的数据流(streaming)是最快也是最透明的选项,而且最适合于文本处理。mrjob最适合于在Amazon EMR上快速工作,但是会有显著的性能损失。dumbo 对于大多数复杂的工作都很方便(对象作为键名(key)),但是仍然比数据流(streaming)要慢。

请继续往下阅读,以了解实现细节,性能以及功能的比较。

一个有趣的问题

为了测试不同的框架,我们不会做“统计词数”的实验,转而去转化谷歌图书N-元数据。 N-元代表一个n个词构成的元组。这个n-元数据集提供了谷歌图书文集中以年份分组的所有1-,2-,3-,4-,5-元记录的统计数目。 在这个n-元数据集中的每行记录都由三个域构成:n-元,年份,观测次数。(您能够在http://books.google.com/ngrams取得数据)。

我们希望去汇总数据以观测统计任何一对相互临近的词组合所出现的次数,并以年份分组。实验结果将使我们能够判断出是否有词组合在某一年中比正常情况出现的更为频繁。如果统计时,有两个词在四个词的距离内出现过,那么我们定义两个词是“临近”的。 或等价地,如果两个词在2-,3-或者5-元记录中出现过,那么我们也定义它们是”临近“的。 一次,实验的最终产物会包含一个2-元记录,年份和统计次数。

有一个微妙的地方必须强调。n-元数据集中每个数据的值都是通过整个谷歌图书语料库来计算的。从原理上来说,给定一个5-元数据集,我可以通过简单地聚合正确的n-元来计算出4-元、3-元和2-元数据集。例如,当5-元数据集包含

(the, cat, in, the, hat)    1999   20
(the, cat, is, on, youtube)  1999   13
(how, are, you, doing, today) 1986  5000

时,我们可以将它聚合为2-元数据集以得出如下记录

(the, cat) 1999  33   // 也就是, 20 + 13

然而,实际应用中,只有在整个语料库中出现了40次以上的n元组才会被统计进来。所以,如果某个5元组达不到40次的阈值,那么Google也提供组成这个5元组的2元组数据,这其中有一些或许能够达到阈值。出于这个原因,我们用相邻词的二元数据,隔一个词的三元组,隔两个词的四元组,以此类推。换句话说,与给定二元组相比,三元组多的只是最外层的词。除了对可能的稀疏n元数据更敏感,只用n元组最外层的词还有助于避免重复计算。总的来说,我们将在2元、3元、4元和5元数据集上进行计算。

MapReduce的伪代码来实现这个解决方案类似这样:

def map(record):
  (ngram, year, count) = unpack(record)
  // 确保word1为字典第一个字
  (word1, word2) = sorted(ngram[first], ngram[last])
  key = (word1, word2, year)
  emit(key, count)

def reduce(key, values):
  emit(key, sum(values))

硬件

这些MapReduce组件在一个大约20GB的随机数据子集上执行。完整的数据集涵盖1500个文件;我们用这个脚本选取一个随机子集。文件名保持完整,这一点相当重要,因为文件名确定了数据块的n-元中n的值。

Hadoop集群包含5个使用CentOS 6.2 x64的虚拟节点,每个都有4个CPU,10GB RAM,100GB硬盘容量,并且运行CDH4。集群每次能够执行20个并行运算,每个组件能够执行10个减速器。

集群上运行的软件版本如下:

  Hadoop:2.0.0-cdh4.1.2
  Python:2.6.6
  mrjob:0.4-dev
  dumbo:0.21.36
  hadoopy:0.6.0
  pydoop:0.7(PyPI)库中包含最新版本
  java:1.6

实现

大多数Python框架都封装了Hadoop Streaming,还有一些封装了Hadoop Pipes,也有些是基于自己的实现。下面我会分享一些我使用各种Python工具来写Hadoop jobs的经验,并会附上一份性能和特点的比较。我比较感兴趣的特点是易于上手和运行,我不会去优化某个单独的软件的性能。

在处理每一个数据集的时候,都会有一些损坏的记录。对于每一条记录,我们要检查是否有错并识别错误的种类,包括缺少字段以及错误的N元大小。对于后一种情况,我们必须知道记录所在的文件名以便确定该有的N元大小。

所有代码可以从 GitHub 获得。

Hadoop Streaming

Hadoop Streaming提供了使用其他可执行程序来作为Hadoop的mapper或者reduce的方式,包括标准Unix工具和Python脚本。这个程序必须使用规定的语义从标准输入读取数据,然后将结果输出到标准输出。直接使用Streaming 的一个缺点是当reduce的输入是按key分组的时候,仍然是一行行迭代的,必须由用户来辨识key与key之间的界限。

下面是mapper的代码:

#! /usr/bin/env python

import os
import re
import sys

# determine value of n in the current block of ngrams by parsing the filename
input_file = os.environ['map_input_file']
expected_tokens = int(re.findall(r'([\d]+)gram', os.path.basename(input_file))[0])

for line in sys.stdin:
  data = line.split('\t')

  # perform some error checking
  if len(data) < 3:
    continue

  # unpack data
  ngram = data[0].split()
  year = data[1]
  count = data[2]

  # more error checking
  if len(ngram) != expected_tokens:
    continue

  # build key and emit
  pair = sorted([ngram[0], ngram[expected_tokens - 1]])
  print >>sys.stdout, "%s\t%s\t%s\t%s" % (pair[0], pair[1], year, count)

下面是reducer:

#! /usr/bin/env python

import sys

total = 0
prev_key = False
for line in sys.stdin:
  data = line.split('\t')
  curr_key = '\t'.join(data[:3])
  count = int(data[3])

  # found a boundary; emit current sum
  if prev_key and curr_key != prev_key:
    print >>sys.stdout, "%s\t%i" % (prev_key, total)
    prev_key = curr_key
    total = count
  # same key; accumulate sum
  else:
    prev_key = curr_key
    total += count

# emit last key
if prev_key:
  print >>sys.stdout, "%s\t%i" % (prev_key, total)

Hadoop流(Streaming)默认用一个tab字符分割健(key)和值(value)。因为我们也用tab字符分割了各个域(field),所以我们必须通过传递给Hadoop下面三个选项来告诉它我们数据的健(key)由前三个域构成。

-jobconf stream.num.map.output.key.fields=3
-jobconf stream.num.reduce.output.key.fields=3

要执行Hadoop任务命令

hadoop jar /usr/lib/hadoop-0.20-mapreduce/contrib/streaming/hadoop-streaming-2.0.0-mr1-cdh4.1.2.jar \
    -input /ngrams \
    -output /output-streaming \
    -mapper mapper.py \
    -combiner reducer.py \
    -reducer reducer.py \
    -jobconf stream.num.map.output.key.fields=3 \
    -jobconf stream.num.reduce.output.key.fields=3 \
    -jobconf mapred.reduce.tasks=10 \
    -file mapper.py \
    -file reducer.py

注意,mapper.py和reducer.py在命令中出现了两次,第一次是告诉Hadoop要执行着两个文件,第二次是告诉Hadoop把这两个文件分发给集群的所有节点。

Hadoop Streaming 的底层机制很简单清晰。与此相反,Python以一种不透明的方式执行他们自己的序列化/反序列化,而这要消耗更多的资源。 而且,如果Hadoop软件已经存在,Streaming就能运行,而不需要再在上面配置其他的软件。更不用说还能传递Unix 命令或者Java类名称作 mappers/reducers了。

Streaming缺点是必须要手工操作。用户必须自己决定如何将对象转化为为成键值对(比如JSON 对象)。对于二进制数据的支持也不好。而且如上面说过的,必须在reducer手工监控key的边界,这很容易出错。

mrjob

mrjob是一个开放源码的Python框架,封装Hadoop的数据流,并积极开发Yelp的。由于Yelp的运作完全在亚马逊网络服务,mrjob的整合与EMR是令人难以置信的光滑和容易(使用 boto包)。

mrjob提供了一个Python的API与Hadoop的数据流,并允许用户使用任何对象作为键和映射器。默认情况下,这些对象被序列化为JSON对象的内部,但也有支持pickle的对象。有没有其他的二进制I / O格式的开箱即用,但有一个机制来实现自定义序列化。

值得注意的是,mrjob似乎发展的非常快,并有很好的文档。

所有的Python框架,看起来像伪代码实现:

#! /usr/bin/env python

import os
import re

from mrjob.job import MRJob
from mrjob.protocol import RawProtocol, ReprProtocol

class NgramNeighbors(MRJob):

  # mrjob allows you to specify input/intermediate/output serialization
  # default output protocol is JSON; here we set it to text
  OUTPUT_PROTOCOL = RawProtocol

  def mapper_init(self):
    # determine value of n in the current block of ngrams by parsing filename
    input_file = os.environ['map_input_file']
    self.expected_tokens = int(re.findall(r'([\d]+)gram', os.path.basename(input_file))[0])

  def mapper(self, key, line):
    data = line.split('\t')

    # error checking
    if len(data) < 3:
      return

    # unpack data
    ngram = data[0].split()
    year = data[1]
    count = int(data[2])

    # more error checking
    if len(ngram) != self.expected_tokens:
      return

    # generate key
    pair = sorted([ngram[0], ngram[self.expected_tokens - 1]])
    k = pair + [year]

    # note that the key is an object (a list in this case)
    # that mrjob will serialize as JSON text
    yield (k, count)

  def combiner(self, key, counts):
    # the combiner must be separate from the reducer because the input
    # and output must both be JSON
    yield (key, sum(counts))

  def reducer(self, key, counts):
    # the final output is encoded as text
    yield "%s\t%s\t%s" % tuple(key), str(sum(counts))

if __name__ == '__main__':
  # sets up a runner, based on command line options
  NgramNeighbors.run()

mrjob只需要安装在客户机上,其中在作业的时候提交。下面是要运行的命令:

export HADOOP_HOME="/usr/lib/hadoop-0.20-mapreduce"
./ngrams.py -r hadoop --hadoop-bin /usr/bin/hadoop --jobconf mapred.reduce.tasks=10 -o hdfs:///output-mrjob hdfs:///ngrams

编写MapReduce的工作是非常直观和简单的。然而,有一个重大的内部序列化计划所产生的成本。最有可能的二进制计划将需要实现的用户(例如,为了支持typedbytes)。也有一些内置的实用程序日志文件的解析。最后,mrjob允许用户写多步骤的MapReduce的工作流程,在那里从一个MapReduce作业的中间输出被自动用作输入到另一个MapReduce工作。

(注:其余的实现都非常相似,除了包具体的实现,他们都能被找到here.。)

dumbo

dumbo 是另外一个使用Hadoop流包装的框架。dumbo出现的较早,本应该被许多人使用,但由于缺少文档,造成开发困难。这也是不如mcjob的一点。

dumbo通过typedbytes执行序列化,能允许更简洁的数据传输,也可以更自然的通过指定JavaInputFormat读取SequenceFiles或者其他格式的文件,比如,dumbo也可以执行Python的egg和Java的JAR文件。

在我的印象中, 我必须要手动安装dumbo中的每一个节点, 它只有在typedbytes和dumbo以eggs形式创建的时候才能运行。 就像他会因为onMemoryErrors终止一样,他也会因为使用组合器停止。

运行dumbo任务的代码是:

dumbo start ngrams.py \
    -hadoop /usr \
    -hadooplib /usr/lib/hadoop-0.20-mapreduce/contrib/streaming \
    -numreducetasks 10 \
    -input hdfs:///ngrams \
    -output hdfs:///output-dumbo \
    -outputformat text \
    -inputformat text

hadoopy

hadoopy是另外一个兼容dumbo的Streaming封装。同样,它也使用typedbytes序列化数据,并直接把 typedbytes 数据写到HDFS。

它有一个很棒的调试机制, 在这种机制下它可以直接把消息写到标准输出而不会干扰Streaming过程。它和dumbo很相似,但文档要好得多。文档中还提供了与 Apache HBase整合的内容。

用hadoopy的时候有两种发发来启动jobs:

  • launch 需要每个节点都已经安装了Python/hadoopy ,但是在这之后的负载就小了。
  • launch_frozen 不要求节点上已经安装了Python,它会在运行的时候安装,但这会带来15秒左右的额外时间消耗(据说通过某些优化和缓存技巧能够缩短这个时间)。

必须在Python程序中启动hadoopy job,它没有内置的命令行工具。

我写了一个脚本通过launch_frozen的方式启动hadoopy

python launch_hadoopy.py

用launch_frozen运行之后,我在每个节点上都安装了hadoopy然后用launch方法又运行了一遍,性能明显好得多。

pydoop

与其他框架相比,pydoop 封装了Hadoop的管道(Pipes),这是Hadoop的C++ API。 正因为此,该项目声称他们能够提供更加丰富的Hadoop和HDFS接口,以及一样好的性能。我没有验证这个。但是,有一个好处是可以用Python实现一个Partitioner,RecordReader以及RecordWriter。所有的输入输出都必须是字符串。

最重要的是,我不能成功的从PIP或者源代码构建pydoop。

其他

  • happy是一个用Jython来写Hadoop job的框架,但是似乎已经挂了
  • Disco成熟的,非Hadoop 的 MapReduce.实现,它的核心使用Erlang写的,提供了Python的API,它由诺基亚开发,不如Hadoop应用广泛。
  • octopy是一个纯Python的MapReduce实现,它只有一个源文件,并不适于“真正的”计算。
  • Mortar是另一个Python选择,它不久前才发布,用户可以通过一个网页应用提交Apache Pig或者 Python jobs 处理放置在 Amazon S3上的数据。
  • 有一些更高层次的Hadoop生态体系中的接口,像 Apache Hive和Pig。Pig 可以让用户用Python来写自定义的功能,是通过Jython来运行。 Hive 也有一个Python封装叫做hipy
  • (Added Jan. 7 2013) Luigi是一个用于管理多步作业流程的Python框架。它与Apache Oozie有一点相似,但是它内置封装了Hadoop Streaming(轻量级的封装)。Luigi有一个非常好的功能是能够在job出错的时候抛出Python代码的错误堆栈,而且它的命令行界面也非常棒。它的README文件内容很多,但是却缺少详尽的参考文档。Luigi 由Spotify 开发并在其内部广泛使用。

本地java

最后,我使用新的Hadoop Java API接口实施了MR任务,编译完成后,这样来运行它:

hadoop jar /root/ngrams/native/target/NgramsComparison-0.0.1-SNAPSHOT.jar NgramsDriver hdfs:///ngrams hdfs:///output-native

关于计数器的特别说明

在我的MR jobs的最初实现里,我用计数器来跟踪监控不良记录。在Streaming里,需要把信息写到stderr。事实证明这会带来不容忽视的额外开销:Streaming job花的时间是原生java job的3.4倍。这个框架同样有此问题。

将用Java实现的MapReduce job作为性能基准。 Python框架的值是其相对于Java的性能指标的比率。

Java明显最快,,Streaming要多花一半时间,Python框架花的时间更多。从mrjob mapper的profile数据来看,它在序列化/反序列化上花费了大量时间。dumbo和hadoopy在这方面要好一点。如果用了combiner 的话dumbo 还可以更快。

特点比较

大多来自各自软件包中的文档以及代码库。

结论

Streaming是最快的Python方案,这面面没有任何魔力。但是在用它来实现reduce逻辑的时候,以及有很多复杂对象的时候要特别小心。

所有的Python框架看起来都像是伪码,这非常棒。

mrjob更新快,成熟的易用,用它来组织多步MapReduce的工作流很容易,还可以方便地使用复杂对象。它还可以无缝使用EMR。但是它也是执行速度最慢的。

还有一些不是很流行的 Python 框架,他们的主要优势是内置了对于二进制格式的支持,但如果有必要话,这个完全可以由用户代码来自己实现。

就目前来看:

  • Hadoop Streaming是一般情况下的最佳选择,只要在使用reducer的时候多加小心,它还是很简单易用的。
  • 从计算开销方面考虑的话,选择mrjob,因为它与Amazon EMR结合最好。
  • 如果应用比较复杂,包含了复合键,要组合多步流程,dumbo 最合适。它比Streaming慢,但是比mrjob快。

如果你在实践中有自己的认识,或是发现本文有错误,请在回复里提出。

(0)

相关推荐

  • windows 32位eclipse远程hadoop开发环境搭建

    本文假设hadoop环境在远程机器(如linux服务器上),hadoop版本为2.5.2 注:本文eclipse/intellij idea 远程调试hadoop 2.6.0主要参考了并在其基础上有所调整 由于我喜欢在win7 64位上安装32位的软件,比如32位jdk,32位eclipse,所以虽然本文中的操作系统是win7 64位,但是所有的软件都是32位的. 软件版本: 操作系统:win7 64位 eclipse: eclipse-jee-mars-2-win32 java: 1.8.0_

  • Hadoop streaming详细介绍

    Hadoop streaming Hadoop为MapReduce提供了不同的API,可以方便我们使用不同的编程语言来使用MapReduce框架,而不是只局限于Java.这里要介绍的就是Hadoop streaming API.Hadoop streaming 使用Unix的standard streams作为我们mapreduce程序和MapReduce框架之间的接口.所以你可以用任何语言来编写MapReduce程序,只要该语言可以往standard input/output上进行读写. st

  • Hadoop 2.x伪分布式环境搭建详细步骤

    本文以图文结合的方式详细介绍了Hadoop 2.x伪分布式环境搭建的全过程,供大家参考,具体内容如下 1.修改hadoop-env.sh.yarn-env.sh.mapred-env.sh 方法:使用notepad++(beifeng用户)打开这三个文件 添加代码:export JAVA_HOME=/opt/modules/jdk1.7.0_67 2.修改core-site.xml.hdfs-site.xml.yarn-site.xml.mapred-site.xml配置文件 1)修改core-

  • Java访问Hadoop分布式文件系统HDFS的配置说明

    配置文件 m103替换为hdfs服务地址. 要利用Java客户端来存取HDFS上的文件,不得不说的是配置文件hadoop-0.20.2/conf/core-site.xml了,最初我就是在这里吃了大亏,所以我死活连不上HDFS,文件无法创建.读取. <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <co

  • Hadoop SSH免密码登录以及失败解决方案

    1. 创建ssh-key 这里我们采用rsa方式,使用如下命令: xiaosi@xiaosi:~$ ssh-keygen -t rsa -f ~/.ssh/id_rsa Generating public/private rsa key pair. Created directory '/home/xiaosi/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identifi

  • Hadoop MapReduce多输出详细介绍

    Hadoop MapReduce多输出 FileOutputFormat及其子类产生的文件放在输出目录下.每个reducer一个文件并且文件由分区号命名:part-r-00000,part-r-00001,等等.有时可能要对输出的文件名进行控制或让每个reducer输出多个文件.MapReduce为此提供了MultipleOutputFormat类. MultipleOutputFormat类可以将数据写到多个文件,这些文件的名称源于输出的键和值或者任意字符串.这允许每个reducer(或者只有

  • 使用Maven搭建Hadoop开发环境

    关于Maven的使用就不再啰嗦了,网上很多,并且这么多年变化也不大,这里仅介绍怎么搭建Hadoop的开发环境. 1. 首先创建工程 复制代码 代码如下: mvn archetype:generate -DgroupId=my.hadoopstudy -DartifactId=hadoopstudy -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 2. 然后在pom.xml文件里添加hadoop的依赖

  • eclipse/intellij idea 远程调试hadoop 2.6.0

    很多hadoop初学者估计都我一样,由于没有足够的机器资源,只能在虚拟机里弄一个linux安装hadoop的伪分布,然后在host机上win7里使用eclipse或Intellj idea来写代码测试,那么问题来了,win7下的eclipse或intellij idea如何远程提交map/reduce任务到远程hadoop,并断点调试? 一.准备工作 1.1 在win7中,找一个目录,解压hadoop-2.6.0,本文中是D:\yangjm\Code\study\hadoop\hadoop-2.

  • java结合HADOOP集群文件上传下载

    对HDFS上的文件进行上传和下载是对集群的基本操作,在<HADOOP权威指南>一书中,对文件的上传和下载都有代码的实例,但是对如何配置HADOOP客户端却是没有讲得很清楚,经过长时间的搜索和调试,总结了一下,如何配置使用集群的方法,以及自己测试可用的对集群上的文件进行操作的程序.首先,需要配置对应的环境变量: 复制代码 代码如下: hadoop_HOME="/home/work/tools/java/hadoop-client/hadoop" for f in $hadoo

  • Hadoop中的Python框架的使用指南

    最近,我加入了Cloudera,在这之前,我在计算生物学/基因组学上已经工作了差不多10年.我的分析工作主要是利用Python语言和它很棒的科学计算栈来进行的.但Apache Hadoop的生态系统大部分都是用Java来实现的,也是为Java准备的,这让我很恼火.所以,我的头等大事变成了寻找一些Python可以用的Hadoop框架. 在这篇文章里,我会把我个人对这些框架的一些无关科学的看法写下来,这些框架包括: Hadoop流 mrjob dumbo hadoopy pydoop 其它 最终,在

  • python框架django基础指南

    Django简介: Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C.不过在Django实际使用中,Django更关注的是模型(Model).模板(Template)和视图(Views),称为 MTV模式.Django的主要目的是简便.快速的开发数据库驱动的网站,它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件. django是对象关系映射的 (ORM,objec

  • python中的测试框架

    一.测试常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过setUp()和setDown()方法处理: 编写执行快速的测试代码.在某些情况下,测试需要加载复杂的数据结构,而且每次执行的时候都要重新加载,这个时候测试执行会很慢.因此,在这种情况下,可以将这种测试放置一个后台的任务中. 在编写代码前执行完整的测试,而且在编写代码后再重新执行一次.这样能保证你后来

  • Python中Pyspider爬虫框架的基本使用详解

    1.pyspider介绍 一个国人编写的强大的网络爬虫系统并带有强大的WebUI.采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项目管理器以及结果查看器. 用Python编写脚本 功能强大的WebUI,包含脚本编辑器,任务监视器,项目管理器和结果查看器 MySQL,MongoDB,Redis,SQLite,Elasticsearch; PostgreSQL与SQLAlchemy作为数据库后端 RabbitMQ,Beanstalk,Redis

  • python中的unittest框架实例详解

    在python中我们学习了不少理论知识,那么对相关的程序进行测试,就显得很重要了.本篇要讲的是unittest框架,我们可以用它来做一些测试工作,又或者是相关代码的编写.下面我们就unittest框架的说明.特性和4种字模块分别带来介绍,大家一起来看具体内容. 1.unittest说明 unittest是Python自带的单元测试框,具备编写用例.组织用例.执行用例.输出报告等自动化框架的条件,可以用来作自动化测试框架的用例组织执行框架. 2.unittest框架特性 (1)提供用例组织与执行:

  • python框架django中结合vue进行前后端分离

    目录 一:创建django项目 二:安装vue 三:设置vue项目 四:vue项目写完后,打包vue项目,然后修改django配置,将vue集成到django中 五:修改django的主目录的urls文件 六:启动django服务,访问localhost:8000 则可以出现vue的首页 七:有时候并不能直接访问出首页,原因是路径不对 八:vue打包之后经常会出现fontawesome图标库不能使用的情况 一:创建django项目 django-admin startproject mysite

  • Python中的flask框架详解

    Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务.本文参考自Flask官方文档,大部分代码引用自官方文档. 安装flask 首先我们来安装Flask.最简单的办法就是使用pip. pip install flask 然后打开一个Python文件,输入下面的内容并运行该文件.然后访问localhost:5000,我们应当可以看到浏览器上输出了hello world. from flask import Flask app = Flask(

  • python中的flask框架Jinja 模板入门教程

    目录 1.快速体验 2.Flask 最小 DEMO 3.模板继承 4.Super Blocks 5.Macros 6.自定义过滤器 7.结论 Flask 和 Django 附带了强大的 Jinja 模板语言. 对于之前没有接触过模板语言的人来说,这类语言基本上就是包含一些变量,当准备渲染呈现 HTML 时,它们会被实际的值替换. 这些变量放在标记或分隔符之前.例如:Jinja 模板使用 {% ... %} 表示循环,{{ ... }} 表示一个表达式运算结果返回. Jinja 模板其实是 htm

  • 10款最好的Web开发的 Python 框架

    Python 是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准 库也是值得大家称赞的,Python甚至还自带服务器.其它方面,Python拥有足够多的免费数据函数库.免费的Web网页模板系统.还有与Web服务 器进行交互的库.这些都可以设计到你的Web应用程序里面.在这篇文章里,我们将为Python Web开发者介绍基于Python的10大Web应用框架. CubicWeb CubicWeb的最重要的

  • Python编码爬坑指南(必看)

    自己最近有在学习python,这实在是一门非常短小精悍的语言,很喜欢这种语言精悍背后又有强大函数库支撑的语言.可是刚接触不久就遇到了让人头疼的关于编码的问题,在网上查了很多资料现在在这里做一番总结,权当一个记录也为后来的兄弟姐妹们服务,如果可以让您少走一些弯路本人将倍感荣幸. 先来描述下现象吧: import os for i in os.listdir("E:\Torchlight II"): print i 代码很简单我们使用os的listdir函数遍历了E:\Torchlight

随机推荐