用 NodeJS 思想学 Python——搭建开发环境

前言:熟悉前端的小伙伴都知道,NodeJS 的模块管理工具 npm 非常好用,但随着 npm 的升级,它管理模块的逻辑越来越复杂,而且模块安装目录 npm_modules 也极其庞杂,难以管理。终于 NodeJS 之父 Ryan Dahl 受不了了,在于 2017 年创立了 Deno。

如果你既熟悉 NodeJS 又了解 Python ,不难发现他俩长得真像哥们,不过虽然长得很像,但是在配置项目环境方面,两者的难易程度,可不是一个水平的。

对于我们前端,想创建一个项目很简单的,直接一个命令行完事:

npm init

但是在 Python 里面可有的忙了,因为 Python 本身的限制,我们要想创建一个开发项目,首先要解决两个问题:

  1. 因为 pip install module_name 会把模块放到全局,所以首先就要解决,不同项目的开发模块不能相互影响。
  2. 项目开发过程中的环境管理问题,我们需要有类似 package.jsonpackage-lock.json 的文件,虽然 pip 可以通过 freeze 生成 requirements.txt,但是这个文件太简陋了。

所以接下里我会从 Python 开发环境演变的历史角度来梳理下,如何快速创建一个像 NodeJS 项目环境的一个 Python 项目。

版本管理问题

我们知道软件是一直在更新的,但是项目一般在建立,就要确定软件的版本,以后不会随意去更新的,这就导致了,因为年代的问题,不同项目依赖相同软件的不同版本。

前端小伙伴都知道,我们一般都是使用 nvm 来管理 NodeJS 版本的,Python 肯定也有这个工具,它叫什么呢?

pyenv,没错 Python 中使用 pyenv 来进行版本管理。

但是 pyenv 的安装比 nvm 稍微麻烦点,不是安装上就能用了,而且因为墙的问题,下载速度垃圾的要命,我们还的手动解决。

pyenv 安装完成之后,我们还的手动配置下,你可以去官网查看安装教程,pyenv-github

我这里通过官网的截图给你,说明下我是如何安装成功的。

github.com_pyenv_pyenv.png

在安装之前,我们可以通过 pyenv install -l 来查看 python 的版本,选一个最新的稳定版,然后使用 pyenv install 3.9.1 命令安装。

不过你安装 python 版本的时候,大概率速度可能过慢,根本下载不下来,所以我们需要镜像,先去 淘宝镜像 找到需要的版本,下载 .tar.xz 的那个,例如 Python-3.9.1.tar.xz,接下来的操作按照这个博客的步骤走:

macOS pyenv入门使用记录

如果安装功能,那么在 ~/.pyenv/versions 就能看到了 :

那么我们怎么使用呢?一般有三种使用方式:

# global 全局设置 一般不建议改变全局设置
pyenv global <python版本>

# shell 会话设置 只影响当前的shell会话
pyenv shell <python版本>
# 取消 shell 会话的设置
pyenv shell --unset

# local 本地设置 只影响所在文件夹
pyenv local <python版本>
# 取消 local  本地的设置
pyenv local --unset

总结:版本管理方面,nvm 完胜 pyenv✌️。

接下来解决我们文章开头抛出来的两个问题。

一、不同项目的模块不互相影响

前端在使用 NodeJS 开发的时候,很少会把项目使用到的模块安装在全局环境,基本都是在本地安装使用的,所以只需要维护好本地依赖文件 package.json 就行了。

但在 Python 中使用第三方模块的时候,很鸡肋了,统一安装到全局,没有安装到本地项目文件夹下的概念。这肯定是不行的,如果多个项目的话,项目模块全给弄到全局,每个项目到底依赖哪些模块,不久傻傻分不清楚了嘛。为了解决这个问题, Python 出现了虚拟环境的概念。

虚拟环境 是通过 virtualenv 来创建的,来看下这个模块的简单安装使用。

$ pip install virtualenv # 安装模块
$ virtualenv myvenv # 创建一个虚拟项目
$ source myvenv/bin/activate # source进入该环境,注意此时命令提示符变了,有个(venv)前缀,表示当前环境是一个名为venv的Python环境。
$ deactivate # 使用deactivate命令,退出当前的venv环境。

但在 pip3.3 之后,Python 内置了一个 venv 模块,用法和 virtualenv 没啥区别 ,但省去了我们的安装等待的问题,所以我们只需要简单的一行命令就能创建一个虚拟环境了:

python3 -m venv project # 创建一个项目
# 剩下的命令和 virtualenv 一致

创建完虚拟环境,当我们在项目中,再手动 install 第三方模块的时候,就能保证模块,只安装在项目目录下。

不过,这时你可能会问,如何保证项目移动过程中的模块维护问题,比如新入职的小 B,使用 git 拉完代码如何安装项目模块,启动应用,Python 又没有类似 NodeJS 管理模块的 package.json 文件。

有解决办法,不过挺麻烦,需要我们手动生成一个类似 NodeJS 项目中的 package.json 文件。

pip freeze > requirements.txt

导出模块到文件,其他小伙伴启动项目的时候,只需要:

pip install -r requirements.txt

我告诉大家为什么不使用 pip freeze 这种方式来管理模块,原因很简单,你的小伙伴 pip install -r requirements.txt 之后,本地没有生成虚拟环境,再安装新的模块,就给安到全局了,到时候 pip freeze > requirements.txt 难免会把其他项目的模块生成到到 requirements.txt 里面。这时候你可能会想,我在 install 之前,手动建一个虚拟环境不就行了,确实很棒,但不麻烦吗……

virtualenv 的有个缺点,没法统一管理,所以又出现了 virtualenvwrapper 来统一管理虚拟环境,来看它的安装和使用方式。

1.安装

# windows
pip install virtualenvwrapper-win
# linux
pip install virtualenvwrapper
2.新建虚拟环境

mkvirtualenv testenv
3.虚拟环境中安装库

pip install requests
4.查看虚拟环境中目前存在的库

pip list
5.查看存在的虚拟环境

workon
6.进入虚拟环境

workon + 虚拟环境名称
7.退出虚拟环境

deactivate
8.删除虚拟环境

rmvirtualenv + 虚拟环境名称

熟悉了 virtualenv 和 virtualenvwrapper,那么 pyenv-virtualenvpyenv-virtualenvwrapper ,相信你也知道是干啥的了,pyenv-virtualenv 完全够用了,pyenv-virtualenvwrapper 我基本不怎么用。

对比着 NodeJS,我们知道 nvm 用来管理 NodeJS 版本,pyenv 用来管理 Python 的版本,一个 node_modules 对应一个前端项目,一个 virtualenv 也对应一个 Python 项目。

到此,Python 的模块管理基本上够用了,但是相比 NodeJS 的 npm 机制还是比较鸡肋,比如 npm 开发环境下有开发依赖,生产环境下有生产依赖。所以 Python 的模块管理还需要进一步加强,加强之后就是 pipenv

接下来就是开头提到的第二个问题的解决办法了。

二、终极大杀器 pipenv

可以简单的认为 pipenv === npm

Pipenv 的官网,是我见过最🐦的一个,你看它的 slogan,for Humans(给人用的),这赤裸裸对 Python 的嘲讽,哈哈哈😂,不过难用也就别怪开发者去吐槽了:

pipenv homesite

来简单看下 pipenv 的安装,如果你不想本地搭建项目,也可以在线体验:https://rootnroll.com/d/pipenv/

# 安装
pip install pipenv
# 查看帮助
pipenv --help
# 查看版本
pipenv --version # pipenv, version 2020.11.15


# 是否安装成功
localhost:~ condorhero$ pip list
Package          Version
---------------- ----------
appdirs          1.4.4
certifi          2020.12.5
distlib          0.3.1
filelock         3.0.12
pip              20.2.3
pipenv           2020.11.15 # this
setuptools       49.2.1
six              1.15.0
virtualenv       20.3.0
virtualenv-clone 0.5.4 # this

接下来看看如何使用 pipenv:

# 新建一个项目并进入
$ mkdir myWeb-py && cd $_
# Create a new project using Python 3.9, specifically:
# 使用 Python 3.9 虚拟化这个项目,这个命令就类似 npm 的 npm init 
$ pipenv --python 3.9
$ pipenv --venv # 查看生成的虚拟环境的位置
/Users/localhostName/.local/share/virtualenvs/myWeb-py-Z_2FicQw

创建成功会在/Users/localhostName/.local/share/virtualenvs/myWeb-py-Z_2FicQw生成虚拟环境,同时在本地生成 Pipfile 文件,Pipfile 为模块管理文件,和 npm 的 package.json 文件功能是一致的,来看下 Pipfile 文件的内容。

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.9"

我来剖析下 Pipfile 文件的内容:

# source 指定下载源,如果你嫌下载速度慢,可以考虑换源,就像 NodeJS 的 npm 换 cnpm 一样
url = "https://mirrors.aliyun.com/pypi/simple"
# 或者使用豆瓣源
url = "http://pypi.douban.com/simple"

# 依赖模块,类似 npm package.json 的 dependencies 字段
[packages]

# 开发环境下的依赖模块,类似 npm package.json 的 devDependencies 字段
[dev-packages]

# 运行需要的版本要求,类似 npm package.json 的 engine 字段
[requires]

# 还有其他的字段例如 [scripts],更多请参考官网 https://pipenv.pypa.io/en/latest/

初始化项目完成之后,我们来实战安装 flask 模块,来试试 pipenv 好不好用:

$ pip list # 先看下全局,有没有安装 flask 模块
$ pipenv install flask # 虚拟环境安装使用 pipenv install 而不再使用 pip install,而且默认安装到 [packages],如果想把模块安装到 dev-packages 下,需要加上 --dev,例如:pipenv install --dev module-name
$ pip list # 再看下全局,有没有安装 flask 模块,两次 pip list 只是为了确定没有把模块安装在全局。
$ ls # 查看目录会发现多出来一个 Pipfile.lock,这个文件和 npm 的 package-lock.json 文件功能是一样的,保证模块有效性。
Pipfile     Pipfile.lock
$ cat Pipfile # 查看  Pipfile 发现 packages 下增加了  flask 模块,`flask = "*"` 表示永远安装最新版的 flask
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
flask = "*"

[dev-packages]

[requires]
python_version = "3.9"

$ pipenv graph # 还可以查看安装模块依赖图
Flask==1.1.2
  - click [required: >=5.1, installed: 7.1.2]
  - itsdangerous [required: >=0.24, installed: 1.1.0]
  - Jinja2 [required: >=2.10.1, installed: 2.11.2]
    - MarkupSafe [required: >=0.23, installed: 1.1.1]
  - Werkzeug [required: >=0.15, installed: 1.0.1]

我们想执行虚拟环境里面的文件,有两种方式:

  • 进入虚拟环境执行:
$ pipenv shell # 可进入虚拟环境,成功进入命令行前面会有括号括起来项目的名字。
(myWeb-py) bash-5.0$ exit # exit 可以退出虚拟环境
  • 不进入虚拟环境执行
$ pipenv run pip list # pipenv run 可以不进入虚拟环境执行命令

一般都是不进入虚拟环境去执行文件,看到 pipenv run 你有没有想到 npm run,如果想到你一定还想到了 npm run 结合 scripts 的用法,没错 pipenv 也有这个功能,编辑 Pipfile 文件增加以下内容,我们新增了三个脚本:

[scripts]
start = "python main.py"
test = "pytest"
list = "pip list"

好了,我们编辑 main.py 使用 flask 来写个服务:

from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def print_hello(): # 视图函数
    # request.args 是个 ImmutableMultiDict
    # language 未定义时,给默认值 PyCharm
    # url 的 query 方法
    language = request.args.get('language', 'PyCharm')
    return f'Hello {language}!'

if __name__ == '__main__':
    app.run()

运行下这个文件:

$ pipenv run start
 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

这里有个WARNING⚠️,原因清楚明了,如果你不想看到它可以通过 pipenv shell FLASK_ENV=development FLASK_APP=main.py flask run 来运行代码。

打开浏览器,输入地址:http://127.0.0.1:5000/?language=World,你会看到:

Flask Hello World

好了,此时如果我想删掉安装的模块重新安装怎么办?类似 NodeJS 的 rm -rf node_modules && npm install 这个动作。

简单我们先删:

# Remove project virtualenv (inferred from current directory):
$ pipenv --rm
$ pipenv --venv # 查看虚拟环境是否还在,确定删除成功

然后我们重新安装模块:

# 重新安装的时候,如果本地没有对应的虚拟环境,会自动重新创建的。
$ pipenv install # 只安装 [packages] 下的模块
$ pipenv install --dev # 既安装 [packages] 下的模块,也安装 [dev-packages] 下的模块

如果还有老项目迁移的话,可以这么做:

pipenv install -r requirements.txt

好了,到此算是入门 pipenv 了。

其实项目中还有一个常用的 anaconda,不过它一般用来开发数据分析项目,因为里面内置了很多东西,不过平时后端开发并不常用:

Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 [1] 因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和 Python)。

总结

Python 和 NodeJS 很像,尤其是在模块管理方面,pip 和 npm 在使用上功能基本一致,但是应用到项目开发中,Python 本身的限制导致了不能像 NodeJS 那样简单有效的建一个项目。为了克服不同项目模块管理的问题,出现了 virtualenv(虚拟环境的说法),但是此时的模块管理依然不够方便,急需一个模块依赖文件。所以出现了大杀器 pipenv。

至此,pipenv 基本上完全实现了 npm 的功能,pipenv使 Python 的 pip 变得更加智能

Python 和 NodeJS 我想你精通任何一个,去学另一个语言都会很容易。

当前时间 Wednesday, January 13, 2021 01:59:45

补充

昨天写好并发布了,结果早上来上班一看,昨天写的东西全没了,哇咔咔……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

  • 写在前面 关于Python虚拟环境管理,曾经做为一名新人一直不以为意,心想反正都是我要用的库,全安装在一起,要用直...
    Stevent阅读 2,672评论 0 50
  • 1、之前写过一篇文章,介绍了pyenv的虚拟环境设置,比较好用,换新电脑后,pyenv install 2.7.1...
    西电大侠阅读 1,480评论 0 0
  • 虚拟环境工具对比 目前接触的开发环境相关: 系统开发环境:Windows、 linux(Ubuntu16.04 l...
    土卡拉阅读 323评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,519评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,562评论 0 11