Python培训
400-996-5531
引言
我们知道,Verilog语言的模块是最底层的功能部件,底层模块在其它模块里被例化,然后又在顶层模块里被例化。这样一级级、一层层构成了一个大项目。
本文共计2500字,阅读大概需要20分钟。
概要:
模块是一块积木,是最基本的功能单位
一切都是以模块的形式存在的
再来理解if __name__ == '__main__'
模块的搜索路径sys.path和PYTHONPATH
安何安装模块(以numpy为例,重点讲离线、非管理员权限安装)
从源码开始安装Tk库
模块是一块积木
在python语言里也一样,模块是最基本的功能单位。我们写一个python脚本,通常需要导入(import)其它模块。比如,如果我们打算获取命令行参数,就需要import sys。如果我们打算新建文件夹,就需要import os。又如果我们打算使用科学计算,就需要import numpy。在python的PyPI ( #/pypi ) 里的第三方模块包已经超过12万个。所以绝大部分时候,我们并不需要从零开始造轮子。
一切都是以模块的形式存在的
在python里,一切都是以模块的形式存在的。可能有人反驳道,他写了一个最简单的Hello world脚本(如下面的hello_world.py),并没有用到、也没有导入任何其它模块。
print("Hello world") #仅此一行
但实际情况是什么呢?python解释器在启动的时候已经帮我们自动导入一个名叫builtins的模块。我们用dir()来帮助理解这一点。在python命令行里输入dir(__builtins__),输出如下的列表:
>>> dir(__builtins__)
[..., 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
是不是发现了这里面包括了print函数(红色)?此处稍微思考一会儿。。。很神奇是吧。是不是还发现了很多常用的函数(蓝色)?所以,不需要导入任何模块就可以直接使用的函数正是builtins模块中的函数。
之前讲函数作用域时讲过,查找变量的规则是“由内向外、由近及远”。这里的“远”就是指builtins模块。如果一直找到builtins模块,仍然没有找到变量的定义,就会报变量未定义的错误。
再来理解if __name__ == '__main__'
一般来说,在python里模块名字就是文件名。我们可以通过内置变量__name__来读取模块名。例如:
>>> print(__name__)
__main__
>>> import sys
>>> print(sys.__name__)
sys
>>> import os
>>> print(os.__name__)
os
当前正在执行的脚本被赋予的模块名字是__main__,相当于C语言的入口函数main()。在《我的第一个Python程序》里,我们写了如下图的程序。我们判断模块的名字是不是__main__来决定要不要调用main(argv)函数。这样写的好处是什么呢?当这个脚本被当作模块来做集成时,模块名是文件名hello(而__main__变成是import hello模块的上层脚本),if __name__ == '__main__'条件里面的语句不会执行。
如果没有if __name__ == '__main__'这一行,在被其它模块导入后,main(argv)会执行两次。
例如下面的例子,有hello_world.py和test.py,位于同一个目录下。
#hello_world.py
def print_hello():
print("hello world")
print_hello() #没有放在if里
#test.py
import hello_world
hello_world.print_hello() #调用函数
结果输出
> python test.py
hello world
hello world
输出了两次hello world?你没看错。一次是hello_world.py里的,另一次是test.py里的。
所以,if __name__ == '__main__'这句的作用就是,让脚本既可以直接当作执行脚本,又可以作当模块被导入。
模块的搜索路径
上面的例子里,我们导入自己写的hello_world模块时提到,须和test.py位于同一个文件夹下。就是说,test.py在import时会在当前目录下查找叫做hello_world.py的文件。
我们可能会有疑问,如果项目做大了必须要分子目录了怎么办?安装第三方模块时是默认安装到了系统目录里,python是如何找到的?又如,如果服务器上安装好几个版本numpy模块库,我们该怎么指定需要的版本?
想搞清楚这些问题,我们就需要先搞清楚python查找模块的规则。我们知道linux在查找可执行命令时是安照PATH环境变量的顺序。类似地,python按照sys.path的顺序来查找模块定义。比如,windows环境下,我们把sys.path打印出来,如下:
>>> import sys
>>> print(sys.path)
['', 'C:\\Python\\Python36\\python36.zip', 'C:\\Python\\Python36\\DLLs', 'C:\\Python\\Python36\\lib', 'C:\\Python\\Python36', 'C:\\Python\\Python36\\lib\\site-packages']
我们可以看到,sys.path其实是列表,里面存着一个个路径。python按照列表的先后顺序,逐个目录查找,直到找到模块定义。知道了这一点,我们就可以根据需要手工改造sys.path的列表,比如把我们自己写的模块目录insert到sys.path的一开头,比如delete掉某个不需要的目录,比如调换两个目录的顺序,等等。(点这里回顾一下列表有哪些操作函数)
另外python启动时还会读取PYTHONPATH的环境变量,并insert到sys.path的一开头。因此,我们也可以修改PYTHONPATH来指定需要的模块所在目录。我们需要结合实际,决定是修改PYTHONPATH还是直接修改sys.path。看哪个可行,看哪个更方便。
如何安装模块
如果你的服务器可以联网,那么恭喜你,你只需要一个命令pip install xxx就可以安装第三方模块。pip是python安装第三方模块的工具。比如,如果你需要安装numpy,只需要pip install umpy即可,安装过程中会自动下载安装依赖包。
有些童鞋立即试了试,却发现“没有pip命令”?那很可能是没有安装pip,或者没有正确设置PATH环境变量。
windows环境下,先看看python安装目录下的scripts文件夹里有没有pip.exe。如果有,就添加C:\Python36\Scripts到环境变量。如下图。
如果Scripts文件夹里没有pip.exe,就需要安装pip了。在控制面板->添加删除软件的找到python,右键点更改,再勾上pip。如下图。
但我们的服务器一般是Linux,如果确认Scripts目录没有pip,就需要去官网下载pip源码包来安装。下载地址:#/pypi/pip/9.0.1,找到pip-9.0.1.tar.gz。解压缩后,用命令python setup.py install安装。
但是,但是,有不少童鞋说,“我们服务器不能连网,也没有管理员权限
”。不用担心,这种情况下,我们需要下载好numpy源码包和所有的依赖包,手动安装到自己的HOME目录或者指定的目录。源码包去哪里下载?当然是去python官网,#/pypi。那么怎么知道要哪些依赖包呢?不用担心,如果缺少依赖包,安装时会报错。缺什么补什么。我整理了安装numpy和matplotlib可能需要的依赖包,见百度网盘https://pan.baidu.com/s/1htmgfYG。
一般来说,安装源码包安装方法是python setup.py install --prefix /home/xxx,其中,--prefix指定安装到自己的HOME目录下,因为我们没有管理员权限。
部分第三方模块,不需要安装,只要解压至一个目录,并加到python的模块搜索路径即可使用。如果遇到某些包实在无法安装,可以试试这种方法。
这里顺便介绍一下,如何安装Tcl和Tk包。一些童鞋在安装matplotlib模块库时,发现python缺少Tk库。分两种情况,如果Linux服务器能联网,且有管理员权限,则优先选用yum install xxx(RHEL、CentOS)或者apt_get install xxx(Ubantu、Debian)。另一种情况就下没联网、没权限,我们下面简单介绍一下源码安装的步骤。
官网#/software/tcltk/download.html下载源码包(tcl8.6.8-src.tar.gz和tk8.6.8-src.tar.gz),并解压目录tcl8.6.8-src和tk8.6.8-src。
先安装tcl,进入tcl8.6.8-src目录,阅读INSTALL和README等说明文件
./configure --prefix=/home/xxx(xxx是你的用户名)
make
make test
make install
再安装tk,进入tk8.6.8-src,安装方法与tcl相同
一般情况下,到这里,你已经可以在python中import tkinter了。但如果你的python也是自己用源码编译安装的话,那很可能你需要重新编译安装python。方法如下:
找到上次编译python的源码目录,如果不幸源码目录被删了,那就重新下载python的源码
进入源码目录,修改Setup和Setup.dist这两个文件中有关tcl和tk的库的路径,如下图白色文件部分。
重新make、make test、make install。
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved