对于 NodeJs
开发的小伙伴,使用 node-gyp
将 C++
模块转换成 NodeJs
的 addon
插件时会依赖 Python
的安装环境(针对使用了 nvm
等版本管理工具的情况)。对于前端小伙伴来说,Python
本身确实不是一个必须学习的语言,但也是一个加分的地方。用 Python
脚本可以帮大家日常处理一些任务,当然了,使用 NodeJs
脚本、Windows
批处理或者 Shell
脚本也可以。
总之上手Python
之后会让大家遇到对应的场景时,肚中有货心不慌。本文也将会以一个 Python
新人入门的痛点和最关注内容的角度切入,首先从 Python
的安装环境开始,然后讲到基本的 Cli
使用,再到Pip
包安装程序(类似于 Npm
依赖包管理工具),然后就是开发实际项目必备的虚拟环境(作用类似于node_modules
隔绝项目依赖),最后就是基本的语法。接下来我们从 Python
安装开始吧!
本文演示的操作系统是Windows10,大家可以在官网python下载地址下载不同的操作系统对应的 Python
支持版本。首先以 windows10
系统 python3.8
版本下载为例,下载对应版本exe文件然后安装,要在安装过程中勾选添加环境变量,如下图所示:
为什么要添加环境变量就不多说了哈!如果忘记添加了环境变量,可以在“我的电脑”上重新配置,安装完成后,重启终端输入如下命令查看是否安装成功:
# 查看已安装版本
python --version
复制代码
如果想查看 python
被安装到了哪里,在 cmd
终端中输入如下命令:
# 查看已安装的python.exe位置
where python
复制代码
环境安装好之后我们就有了 Python
的解释器,可以直接在终端输入 Python
命令进入 Python
的解释器进行代码练习了。然鹅!鹅鹅鹅!更好的模式还是要写一个 Python
文件,然后执行这个 Python
文件,就像一个 Js
文件然后使用 Node
命令执行脚本一样。
Python
安装后添加了环境变量之后,可以使用 python
在终端执行命令。如果要执行一个 python
文件,命令如下:
python path/to/your/pythonfile
复制代码
还可以通过-m
参数可以指定运行某个 python
模块,比如内置的 pip
模块下载包,或者venv
模块创建虚拟环境等:
# 通过pip模块安装xxx包
python -m pip instal xxx
# 通过venv创建虚拟环境
python -m venv your-env-name
复制代码
为了让大家好理解这个概念,有点类似使用 npx
运行一些模块,比如npx eslint
等等,相信到这里大家也就都能理解这个概念了。接下来我们就继续了解 Python
里面的包安装程序:
在前端开发时,包依赖管理程序工具比较多,常见的 npm
、yarn
、cnpm
之外,还有多包依赖解决方案 lerna
,但是在 Python
中官方推荐的包管理程序是pip
。就像 NodeJs
内置了 Npm
模块一样,从 Python 3.4
开始,它默认包含在 Python
二进制安装程序中。
pip
的第三方包仓库地址是pypi.org/,可以在这个网页上搜索第三方包。 基本使用命令如下:
# 安装指定包
python -m pip install packgeName
复制代码
安装指定版本的命令如下:
# 安装指定的具体版本
python -m pip install packgeName==1.0.4
# 安装不低于某个版本的包
python -m pip install "packgeName>=1.0.4"
复制代码
这里通过运行 python -m
命令的方式还是有些略长的,稍安勿躁,后面讲完虚拟环境之后再说怎么简化命令。
什么是虚拟环境呢?
做个和前端环境的类比吧,比如 npm i pkgName -g
的形式安装的依赖包都是放在全局的,这样的话如果不同的项目使用同一个包的不同的版本,就会冲突了。因此前端的每个项目都使用 npm
在当前项目根目录的 node_modules
安装各自项目的依赖包,这样项目直接就不存在依赖冲突了。
Python
虚拟环境也是解决同样问题的,它通过为每个项目创建各自单独的 Python
环境,然后将每个项目各自的依赖包撞到各自的虚拟环境中。
虚拟环境(virtual environment
)是一种采用协作式隔离的运行时环境,在安装和升级依赖包时不会干扰到同一系统上的其他 Python
程序。类似于前端每个项目都有一个 node_modules
隔绝项目之间的依赖包。和前端不同的是,虚拟环境需要通过工具手动创建一个,而前端项目默认是将第三方包直接装在当前项目的目录下的。
下面我们将介绍两种创建虚拟环境的工具:
venv
是创建虚拟环境的标准工具,从 Python 3.3
版本开始默认内置,而从 Python 3.4
开始 venv
会默认安装 pip
到所创建的虚拟环境。使用 venv
创建虚拟环境的命令如下:# 项目目录下终端运行
# -m venv是使用venv模块创建虚拟环境
# visualenv是起的虚拟环境名字,可以换成其他的
python -m venv visualenv
复制代码
虚拟环境创建完成后,可以看到生成了对应文件夹目录,如下图所示:
virtualenv
是 venv
的第三方替代(及其前身)。 它允许在 Python 3.4
之前的版本中使用虚拟环境,那些版本不提供 venv
或者不会自动安装 pip
到所创建的虚拟环境。如果想使用 virtualenv
,需要先使用pip
安装virtualenv
包,安装命令如下所示:
# 安装visualenv
python -m pip install virtualenv
复制代码
安装完成如上述所示,可以再使用 pip
命令查询下所有安装内容是否存在 visualenv
:
# 查看pip的安装列表
python -m pip list
复制代码
visualenv
安装完成后可以用来安装虚拟环境了,如下命令所示:
# 安装虚拟环境
python -m virtualenv my-env
复制代码
总结:虽然 venv
和 virtualenv
都可以用来安装虚拟环境,但是还是推荐在 python3.4
以后的版本使用标准的 venv
来安装虚拟环境。
虚拟环境安装完成后,想将第三方包安装到到虚拟环境中,而不是全局环境中,则需要使用虚拟环境中的 python.exe
运行 pip
模块安装第三方包,如下所示:
# 进入到虚拟环境中python.exe所在文件夹
cd ./visualenv/Scripts
# 运行对应的命令
python.exe -m pip install packageName
复制代码
然而更快捷的做法是激活虚拟环境,从而简化操作命令:
# 进入指定目录
cd ./visualenv/Scripts
# 运行对应操作系统的激活脚本,windows的bat为例
activate.bat
复制代码
激活成功后终端会进入如下图所示的状态:
此时便可以直接运行 pip
命令将依赖包安装到虚拟环境了:
# 安装到虚拟环境
pip install arrow
复制代码
如果是使用的像 Pycharm
编辑器,或者 Vscode
编辑器安装对应的插件等,则可以更快捷的在打开控制台时自动进入虚拟环境。
一切准备就绪,下面就可以开心撸码了。对于 Python
基础的语法,有开发经验的开发小伙伴都是可以非常迅速的上手的。而一些本身属于系统能力,比如文件 IO
、网络、进程线程等等,这些其实也都是通用的,所以打好计算机基础还是很有必要的哈!
下面开始进入 Python
基本语法的学习了,这部分的语法和概念对于有编程语言经验的小伙伴应该是很好上手的。
Python
没有行尾结束符号Python
根据换行进行代码块的区分#
号# 输出 hello py
print('hello py')
复制代码
变量定义不使用关键词,可以使用等号直接赋值:
numData = 123
复制代码
# 定义数值变量
numData = 123
# 定义字符串变量
strData = 'a string data'
# 定义布尔类型,注意大小写
boolTrue = True
boolFalse = False
# 定义None类型数据
none = None
复制代码
列表数据使用[]
包含一组数据,数据可以重复:
# 定义列表数据
listData = ['a', 'b', 1, 2]
# 输出 ['a', 'b', 1, 2]
print(listData)
复制代码
元祖使用逗号定义一组数据,数据是 immutable
不可变类型数据,可以不使用()
进行包裹
# 定义元组,元组数据是不可变类型的数据
tupleA = 1, 2, 'asd'
# 输出 (1, 2, 'asd')
print(tupleA)
tupleB = (1, 2, 'asd')
# 输出 (1, 2, 'asd')
print(tupleB)
复制代码
通过 {}
的语法定义一组集合数据,集合区别于列表的点在于集合是不可重复数据:
# 集合,一组不可重复数据
coll = {'a', 'b', 'b', 'c'}
# 输出{'b', 'c', 'a'}
print(coll)
复制代码
定义空集合不能使用{}
语法,而是set()
, {}
表示空字典:
# 定义空集合
emptySet = set()
print(emptySet)
复制代码
使用 {}
的 key/value
的形式定义字典,类似于js
的对象概念,key
必须要用引号:
# 字典
obj = {
'a': 1,
'b': 'a',
'd': [],
}
print(obj)
复制代码
if
条件语句# if语句
x = 11
if x > 0:
x = 1
# 输出 1
print(x)
复制代码
if/else
语句if x < 0:
x = 1
else:
x = 2
# 输出2
print(x)
复制代码
if/elif
语句if x < 0:
x = 1
elif x < 10:
x = 2
else:
x = 3
# 输出 2
print(x)
复制代码
for/in
循环迭代一个列表数据# 定义列表数据
arr = ['abc', 'defg', 'h']
# 迭代列表
for w in arr:
# 打印每一项内容及其长度
# 依次输出: abc 3; defg 4; h 1
print(w, len(w))
复制代码
不是对拷贝的副本操作,操作的还是原数据
for w in arr[:]:
arr.insert(0, w);
# 输出 ['h', 'defg', 'abc', 'abc', 'defg', 'h']
print(arr)
复制代码
range
函数range
返回的是一个可迭代对象,并不是返回的一个序列,对可迭代对象的可以进行遍历,这样的是可以节省空间:
for i in range(3):
# 依次输出 0 1 2
print(i)
复制代码
验证range
返回的是一个可迭代对象,而不是一个序列,看下其打印内容:
# 输出range(0, 10)
print(range(10))
复制代码
list可以从迭代对象中返回列表数据:
# 输出 [0, 1, 2, 3]
print(list(range(4)))
复制代码
使用 def
关键词定义函数,函数没有显示声明返回内容时,默认返回 None
类型数据:
# 定义fn函数,接收一个name参数
def fn(name):
print('hello', name)
# 函数调用,输出 hello fn
result = fn('fn')
# 函数返回结果,输出None
print(result)
复制代码
python中函数会形成一块作用域,内部作用域可以访问外部的变量,但是默认情况下不可用修改外部的变量:
def fn():
name = 'jack'
def local_fn():
# 输出 local_fn jack
print('local_fn', name)
def local_fn2():
name = 'tommy'
# 输出 local_fn2 tommy
print('local_fn2', name)
local_fn()
local_fn2()
# 输出 fn jack
print('fn', name)
fn()
复制代码
修改外部作用域可以使用nonlocal
、global
等关键词
通过class
语法定义类,类上 x = y
的形式定义属性, 使用 def
关键词定义类的方法。
def __init__():
特殊的名称定义构造方法,类似于 js
的类的 constructor
关键词。实例化时 __init__
构造函数会被调用,其形参第一个是指向该类,后续的形参都是实例化时传入的参数。
实例化类时类似于函数调用,类名()
的格式:
# 定义类
class People:
# 类的属性
name = 'mike'
# 类的构造函数
# 第一个参数指当前类,后续参数是实例化类的参数
def __init__(self, age):
self.age = age
# 类的方法
def say(self):
print(self.name)
# 实例化类
p = People(24)
# 输出24
print(p.age)
# 输出mike
p.say()
复制代码
python
类支持继承和多重继承,基本语法如下:
# 定义基类
class BaseClass:
name = 'mike'
def say(self):
print(self.name)
# 定义派生类
class SubClass(BaseClass):
def find(self):
print(self.name)
p = SubClass()
# 输出mike
p.find()
# 输出mike
p.say()
复制代码
派生类会继承基类的属性和方法,覆盖基类的同名方法,属性及方法的查找沿着当前类到基类的顺序查找下去,直到查找到为止。
多重继承使用逗号的方式进行隔开:
class SubClass(BaseClass1, BaseClass2):
# ...
复制代码
目前没有私有变量的语法,但是通常使用 _
开头的命名表示私有变量,是一种约定俗成的方式。
raise
关键词抛出错误try/except/finally
进行错误处理注意,except 错误类型:
的语法类似于 js
的 catch
概念,但是 except
必须要匹配指定类型的错误才会进入该分支,而 js
的 catch
是只要错误产生就会进入分支:
# 错误捕获
# raise主动抛出错误,except支持捕获指定类型的错误
# finally 不管抛出错误还是成功都执行的代码
try:
raise NameError('a name error')
except NameError:
print('except error')
finally:
print('finally run code')
复制代码
import
导入模块# 导入标准库的os模块
import os
# 导入标准库的shutil模块
import shutil
# 打印当前进程路径
print(os.getcwd())
# 将./yarn.lock文件拷贝到./yarn.lock2
shutil.copyfile('./yarn.lock', './yarn.lock2')
复制代码
form
指定从哪里导入# 从标准库的os模块导入getcwd方法
from os import getcwd
# 打印当前进程路径
print(getcwd())
复制代码
# 导入第三方包arrow,前提是先安装该包
import arrow
print(arrow.get('2013-05-11T21:23:58.970460+07:00'))
utc = arrow.utcnow().to('US/Pacific')
print(utc.timestamp())
复制代码
到这里基本就结束了 Python
基础入门了,本文也是更多的是从小白入门最疑惑的部分开始,把环境安装和基础的工程环境做了介绍。基本上对于新入坑的小伙伴,把工程和环境相关的坑踩平了心里也就有了信心了。
本文也是从前端的视角切入,把 python
和前端相关的概念做了一些关联,希望助入门 Python
的前端小伙伴一臂之力。