目录
模块概念
在Python中,一个.py文件就称之为一个模块(Module)。使用模块组织代码,最大的好处是大大提高了代码的可维护性
模块一共三种:python标准库、第三方模块、应用程序自定义模块。
相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。
对module的理解
和Java中一个类就是一个文件不同(当然不考虑内部类),python中一个.py文件可以包含多个class。Modules的目的是代码的划分、管理以及代码重用。一个module是一个包含了定义和代码的文件,个人认为module包含了针对功能的相关代码,在一个module中可以存在多个类、函数甚至是需要预执行的脚本。
compile&cache
为了加快加载速度python会缓存.py文件,在__pycache__指定的目录中缓存文件按照“module.version.pyc”的名称保存,其中version部分是python的版本信息,这样使得不同版本的缓存可以共存。在引入module时python会检查是否存在缓存和缓存版本是否过期。但是以下两种情况,python不会加载缓存文件:
-
command line中执行python时每次都会重新编译,不会尝试加载。
-
不存在源文件时,python不会直接从缓存中加载*.pyc文件。
python是脚本语言但是存在一个“编译”的概念,其实python的编译时去除了代码中非必须的部分——assert和__doc__部分。“编译”并不是回想Java那样进行代码优化,“编译”的目的在于加快module加载的速度。编译时使用参数-O会忽略掉assert部分,使用-OO会同时忽略assert和__doc__,优化过的代码会保存为*.pyo的文件。
dir
dir()是python中内置的命令返回一个字符串数组,可以用来查看一个module声明的名称。通过dir(module_name)查看一个module声明的名称,不提供参数的情况下会返回当前文件的声明信息。
作为脚本执行
module本身就可以作为python脚本执行,命令行中通过python module.py可以直接执行module,除此以外在import时如果被引入的module中有独立的代码(即不是class或者function的定义)也会被执行。如果希望只在作为独立脚本时被执行,可以写成如下:
if __name__ == '__main__':
print('your code.')
Module的查找路径
python会通过两个地方查找被引入的module——builtins和sys.path。builtins是python内置的标准函数库,可能因不同的平台而有所不同,sys.path则分为项目目录和PYTHONPATH两部分。当
一个module被引入时,python先查找builtins,如果没有找到则尝试在当前目录查找,如果仍然没有则查找PYTHONPATH也就是python的site-package目录。因此如果在项目目录中声明了和PYTHONPATH中同名的module,那么项目目录中的module会优先加载。
与package关系
python中的package就是代码在的目录路径,通过"."的表达式标识。在pythong中可以通过from aaa.bbb import ccc和import aaa.bbb.ccc或者fromaaa import bbb.ccc来达到引入ccc的目的,不同之处是import之后的内容在使用时需要提供全名称,也就是上述三种写法在使用时分别要调用:ccc.fun()、aaa.bbb.ccc.fun()、bbb.ccc.fun()。
package所在的目录需要包含一个空文件__init__.py来表明这个是一个python package,同时在__init__.py文件中可以声明一些描述性的代码来变更package的特性。比如针对import *的__all__,正常情况下我们写from aaa.bbb import *会引入位于aaa/bbb目录下的所有modules——这是一个不好的实践,因为有些东西可能会有副作用。特别的如果某个package下有你明确不希望被引用的py文件,可以通过__all__明确说明哪些是希望引入的,这样在python处理import *时会忽略掉不在__all__列表的内容。如下面的__init__.py指明了在import *时只有persons这个module会被引入。
__author__ = 'Administrator'
__all__ = ['persons',]
模块导入
导入
python中,每个py文件被称之为模块,每个具有__init__.py文件的目录被称为包。只要模
块或者包所在的目录在sys.path中,就可以使用import 模块或import 包来使用
同一目录
如果你要使用的模块(py文件)和当前模块在同一目录,只要import相应的文件名就好,比如在a.py中使用b.py:
import b
注意:
一个模块可以在当前位置import多次,但是只有第一次导入会执行内容,其他的都为引用内存
更改调用名称:
import logging as log
log.critical("www")
from…import语句
from modname import name1[, name2[, … nameN]]
这个声明不会把整个modulename模块导入到当前的命名空间中,只会将它里面的name1或name2单个引入到执行这个声明的模块的全局符号表。
不同目录
但是如果要import一个不同目录的文件(例如b.py)该怎么做呢?
首先需要使用sys.path.append方法将b.py所在目录加入到搜素目录中。然后进行import即
可,例如
import sys
sys.path.append('c:\xxxx\b.py') # 这个例子针对 windows 用户来说的
大多数情况,上面的代码工作的很好。但是如果你没有发现上面代码有什么问题的话,可要
注意了,上面的代码有时会找不到模块或者包(ImportError: No module named
xxxxxx),这是因为:
sys模块是使用c语言编写的,因此字符串支持 ‘\n’, ‘\r’, '\t’等来表示特殊字符。所以
上面代码最好写成:
sys.path.append('c:\\xxx\\b.py')
或者sys.path.append('c:/xxxx/b.py')
这样可以避免因为错误的组成转义字符,而造成无效的搜索目录(sys.path)设置。
sys.path是python的搜索模块的路径集,是一个list
可以在python 环境下使用sys.path.append(path)添加相关的路径,但在退出python环境后
自己添加的路径就会自动消失了!
python在不同层级目录import模块的方法
使用python进行程序编写时,经常会调用不同目录下的模块及函数。本篇博客针对常见的模块调用讲解导入模块的方法。
1. 同级目录下的调用
目录结构如下:
– src
|– mod1.py
|– test1.py
若在程序test1.py中导入模块mod1, 则直接使用
*import mod1*或from mod1 import *;
2. 调用子目录下的模块
目录结构如下:
– src
|– mod1.py
|– lib
| |– mod2.py
|– test1.py
这时,如果想在程序test1.py中导入模块mod2.py ,可以在lib件夹中建立空文件__init__.py文件
新的目录结构如下:
– src
|– mod1.py
|– lib
| |–__init__.py
| |– mod2.py
|– test1.py
然后使用:
from lib.mod2 import *或import lib.mod2.
3. 调用上级目录下的文件
目录结构如下:
– src
|– mod1.py
|– lib
| |– mod2.py
|– sub
| |– test2.py
这里想要实现test2.py调用mod1.py和mod2.py ,做法是我们先跳到src目录下面,直接可以调用mod1,然后在lib上当下建一个空文件__init__.py ,就可以像第二步调用子目录下的模块一样,通过import lib.mod2进行调用了。具体代码如下:
import sys
sys.path.append('C:\\test\\A\\C')
import mod1
import lib.mod2
需要注意的一点是:sys.path添加目录时注意是在windows还是在Linux下,windows下需要‘\'否则会出错。
补充__init__.py
在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有__init__.py 那么它就是这个包的子包了。当你将一个包作为模块导入(比如从 xml 导入 dom )的时候,实际上导入了它的__init__.py 文件。
一个包是一个带有特殊文件 init.py 的目录。init.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。如果 init.py 不存在,这个目录就仅仅是一个目录,而不是一个包,它就不能被导入或者包含其它的模块和嵌套包。
init.py 中还有一个重要的变量,叫做__all__。
如果此时目录如下
– src
|– mod1.py
|– lib
| |– mod2.py
| |– mod3.py
| |– sub
| |– | |– mod3.py
我们有时会使出一招“全部导入”,也就是这样:
from lib import *
这时 import 就会把注册在包__init__.py 文件中 all 列表中的子模块和子包导入到当前作用域中来。比如:
#文件__init__.py
__all__ = ["mod2", "mod3", "sub"]
import、from module import packet使用规则示例
你可以使用import语句将一个源代码文件作为模块导入.例如:
# file : spam.py
a = 37 # 一个变量
def foo: # 一个函数
print "I'm foo"
class bar: # 一个类
def grok(self):
print "I'm bar.grok"
b = bar() # 创建一个实例
使用import spam 语句就可以将这个文件作为模块导入。系统在导入模块时,要做以下三件事:
- 为源代码文件中定义的对象创建一个名字空间,通过这个名字空间可以访问到模块中定义的函数及变量。
- 在新创建的名字空间里执行源代码文件.
- 创建一个名为源代码文件的对象,该对象引用模块的名字空间,这样就可以通过这个对象访问模块中的函数及变量,如:
import spam # 导入并运行模块 spam
print spam.a # 访问模块 spam 的属性
spam.foo()
c = spam.bar()
用逗号分割模块名称就可以同时导入多个模块:
import socket, os, regex
模块导入时可以使用 as 关键字来改变模块的引用对象名字:
import os as system
import socket as net, thread as threads
system.chdir("..")
net.gethostname()
使用from语句可以将模块中的对象直接导入到当前的名字空间. from语句不创建一个到模块名字空间的引用对象,而是把被导入模块的一个或多个对象直接放入当前的名字空间:
from socket import gethostname # 将gethostname放如当前名字空间
print gethostname() # 直接调用
socket.gethostname() # 引发异常NameError: socket
from语句支持逗号分割的对象,也可以使用星号(*)代表模块中除下划线开头的所有对象:
from socket import gethostname, socket
from socket import * # 载入所有对象到当前名字空间
不过,如果一个模块如果定义有列表__all__,则from module import * 语句只能导入__all__列表中存在的对象。
# module: foo.py
__all__ = [ 'bar', 'spam' ] # 定义使用 `*` 可以导入的对象
另外, as 也可以和 from 联合使用:
from socket import gethostname as hostname
h = hostname()
import 语句可以在程序的任何位置使用,你可以在程序中多次导入同一个模块,但模块中的代码仅仅在该模块被首次导入时执行。后面的import语句只是简单的创建一个到模块名字空间的引用而已。sys.modules字典中保存着所有被导入模块的模块名到模块对象的映射。这个字典用来决定是否需要使用import语句来导入一个模块的最新拷贝.
from module import * 语句只能用于一个模块的最顶层.特别注意:由于存在作用域冲突,不允许在函数中使用from 语句。
每个模块都拥有 name 属性,它是一个内容为模块名字的字符串。最顶层的模块名称是 main ,命令行或是交互模式下程序都运行在__main__ 模块内部。 利用__name__属性,我们可以让同一个程序在不同的场合(单独执行或被导入)具有不同的行为,象下面这样做:
# 检查是单独执行还是被导入
if __name__ == '__main__':
# Yes
statements
else:
# No (可能被作为模块导入)
statements
主要用在调试功能,即一个模块被调用的时候不执行内容,而自己调试模块的时候可以顺利的执行模块内容。
重新导入模块
如果更新了一个已经用import语句导入的模块,内建函数reload()可以重新导入并运行更新后的模块代码.它需要一个模块对象做为参数.例如:
import foo
... some code ...
reload(foo) # 重新导入 foo
在reload()运行之后的针对模块的操作都会使用新导入代码,不过reload()并不会更新使用旧模块创建的对象,因此有可能出现新旧版本对象共存的情况。 注意 使用C或C++编译的模块不能通过 reload() 函数来重新导入。记住一个原则,除非是在调试和开发过程中,否则不要使用reload()函数.
包的概念
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。
可以使用import导入包,或者from + import来导入包中的部分模块。
每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录(文件夹),而不是一个包。init.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是对应包的名字。
最简单的情况下,只需要一个空的 init.py 文件即可。当然它也可以执行包的初始化代码。调用包就是执行包下的__init__.py文件。然后是一些模块文件和子目录,假如子目录中也有 init.py 那么它就是这个包的子包了。
多个关系密切的模块应该组织成一个包,以便于维护和使用。这项技术能有效避免名字空间冲突。创建一个名字为包名字的文件夹并在该文件夹下创建一个__init__.py 文件就定义了一个包。你可以根据需要在该文件夹下存放资源文件、已编译扩展及子包。举例来说,一个包可能有以下结构:
Graphics/
__init__.py
Primitive/
__init__.py
lines.py
fill.py
text.py
...
Graph2d/
__init__.py
plot2d.py
...
Graph3d/
__init__.py
plot3d.py
...
Formats/
__init__.py
gif.py
png.py
tiff.py
jpeg.py
包的导入
包导入的几种情况
import语句使用以下几种方式导入包中的模块:
- import Graphics.Primitive.fill #导入模块Graphics.Primitive.fill,只能以全名访问模块属性,例如 Graphics.Primitive.fill.floodfill(img,x,y,color).
- from Graphics.Primitive import fill# 导入模块fill ,只能以 fill.属性名这种方式访问模块属性,例如 fill.floodfill(img,x,y,color).
- from Graphics.Primitive.fill import floodfill #导入模块fill ,并将函数floodfill放入当前名称空间,直接访问被导入的属性,例如 floodfill(img,x,y,color).
- **无论一个包的哪个部分被导入, 在文件__init__.py中的代码都会运行.**这个文件的内容允许为空,不过通常情况下它用来存放包的初始化代码。导入过程遇到的所有 init.py文件都被运行.因此 import Graphics.Primitive.fill 语句会顺序运行 Graphics 和 Primitive 文件夹下的__init__.py文件.
需要注意的是 from package import item 方式导入包时,这个子项(item)既可以是子包也可以是其他命名,如函数、类、变量等。若无,会引发ImportError异常。
而用类似 import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是类、函数、变量等。
从 * 导入包
下边这个语句具有歧义:
- from Graphics.Primitive import *
这个语句的原意图是想将Graphics.Primitive包下的所有模块导入到当前的名称空间.然而,由于不同平台间文件名规则不同(比如大小写敏感问题), Python不能正确判定哪些模块要被导入.这个语句只会顺序运行 Graphics 和 Primitive 文件夹下的__init__.py文件. 要解决这个问题,应该在Primitive文件夹下面的__init__.py中定义一个名字all的列表,例如:
# Graphics/Primitive/__init__.py
__all__ = ["lines","text","fill",...]
这样,上边的语句就可以导入列表中所有模块.
import * 这样的语句理论上是希望文件系统找出包中所有的子模块,然后导入它们。这可能会花长时间,并出现边界效应等。Python 解决方案是提供一个明确的包索引。
这个索引由 init.py 定义 all 变量,该变量为一列表,如上例 sound/effects 下的 init.py 中,可定义 all = [“echo”,“surround”,“reverse”]
这意味着, from sound.effects import * 会从对应的包中导入以上三个子模块; 尽管提供 import * 的方法,仍不建议在生产代码中使用这种写法。
下面这个语句只会执行Graphics目录下的__init__.py文件,而不会导入任何模块
import Graphics
Graphics.Primitive.fill.floodfill(img,x,y,color) # 失败!
不过既然 import Graphics 语句会运行 Graphics 目录下的 init…py文件,我们就可以采取下面的手段来解决这个问题:
# Graphics/__init__.py
import Primitive, Graph2d, Graph3d
# Graphics/Primitive/__init__.py
import lines, fill, text, ...
这样import Graphics语句就可以导入所有的子模块(只能用全名来访问这些模块的属性).
在一个包中,同一目录下的两个模块可以互相引用而不需要提供包的名字.例如 Graphics.Primitive.fill模块可以使用import lines导入Graphics.Primitive.lines . 不过如果两个模块位于同一个包的不同目录,就必须提供包名.例如,如果Graphics.Graph2d的plot2d模块需要使用Graphics.Primitive下的lines模块,就必须使用from Graphics.Primitive import lines这样的语句.
name 属性
如果需要,一个模块可以通过 name 属性得到自己的全名.例如:下面的代码在仅知道同级子包的名字情况下(不知道它们共同的顶级包名)导入该子包下的一个模块。
# Graphics/Graph2d/plot2d.py
# 决定包的名称,以及自身的位置
import string
base_package = string.join(string.split(__name__,'.')[:-2],'.')
# 导入 ../Primitive/fill.py 模块
exec "from %s.Primitive import fill" % (base_package,)
最后,当Python导入一个包时,它定义了一个包含目录列表的特殊变量__path__ ,它用于查找包的模块(path__与sys.path变量的作用相似). 可以在__init.py文件中访问__path__变量.这个列表的初始值只有一个元素.即包的目录.只要你觉得必要,一个包也可以到其他的目录中去(在__path__增加要搜索的目录)搜索模块。(换言之,一个模块可以属于一个包,却不位于这个包所在的目录或子目录下。
sys.path 和sys.modules
sys.path包含了module的查找路径;
sys.modules包含了当前所load的所有的modules的dict(其中包含了builtin的modules);
第三方包的安装及导入
安装
Pip安装使用
pip是用于安装PyPI中所列出的package的工具。PyPI即Python Package Index,是python提供的一个lib的在线仓库类似于Java的maven。pip的功能包括几方面:安装、卸载、升级、查看和本地安装、配置。
Install、List、Local Install、Search
pip用于安装package的命令install,使用命令pip install somepackage完成安装。一般情况下pip会选择最新的版本安装,可以通过参数version指定希望的package版本。除了单个package的安装pip还可以通过requirement file进行批量安装,命令:pip install -r requirement.txt。requirement file本身就是一个包含多个package列表文本文件,并且可以接受version等参数。使用requirement file的目的包括:
-
可重复安装,对于团队的生产环境需要安装统一的配置,可以直接用requirement file搞定。
-
解决依赖,pip默认安装最新的版本,但是多个package之间可能需要特定的版本来相互配合,可以把构建好的环境整理成requirement file。
-
安装特定的版本,比如新的版本可能引入了bug或者冲突,所以使用requirement file来指定一个版本。
-
自定义源文件的安装,软件中存在bug并且你已经等不及原作者去修复了。你自己修复后可以使用requirement file指定某一package从特定路径安装。
pip还支持wheel格式的安装,wheel是一种package的压缩格式要比通过源码的安装快速,默认情况下pip优先选择wheel格式安装,只有在无法找到wheel文件时才会从源文件安装。wheel是pip的一个模块,通过一下命令可以把源文件打包成wheel和从指定wheel文件安装package:
#打包
pip wheel --wheel-dir=/your_wheel_directory -r requirement.txt
#安装
pip install --no-index --find-links=/your_wheel_directory -r requirement.txt
pip支持从本地文件进行安装,对于重复安装的场景免除了每次网络传输的开销,通过下面命令自动下载打包安装文件和进行安装:
#下载
pip install --download <DIR> -r requirements.txt
#安装
pip install --no-index --find-links=[file://]<DIR> -r requirements.txt
pip通过list命令查看已经安装的package或者是过期的package,通过show命令查看文件的详细信息。
#查看已经安装的package
pip list
#查看过期的package
pip list --outdated
#查看某个package的详细
pip show Django
pip提供了search命令用来查找PyPI中的package信息,如pip search django。
Uninstall、Upgrade
需要删除一个package使用命令pip uninstall package_name即可,同样的需要升级一个package也可以通过命令pip upgrade package_name实现。需要注意的是pip的upgrade命令是递归的,也就是新版本的package所依赖的sub_package如果有新版也会被同时更新,即便现有的版本已经满足需求,不希望递归更新时使用命令:
pip install --upgrade --no-deps SomePackage
pip install SomePackage
第一行的命令会更新package但是不会安装依赖,第二行命令会按照SomePackage需要的但是没有安装的package。
Configuration
不同的操作系统平台pip的安装文件位置有所不同,Linux和MacOS中位于%HOME%/pip/pip.conf,Windows下位于%HOME/pip/pip.ini。pip的配置可以分为两个作用范围:整体和子命令。比如:
[global]
timeout = 60
[freeze]
timeout = 10
global规定pip连接的超时时间是60秒,而freeze模块(即requirement file)的超时时间是10秒。除此之外pip的配置还可以通过环境变量和命令行参数传递,三者的优先级是:命令行参数>环境变量>配置文件。比如timeout参数还可以通过下面途径设置:
#设置环境变量
export PIP_DEFAULT_TIMEOUT=60
#命令行参数
pip --default-timeout=60 [...]
常用的pip参数有:
- timeout:设置超时时间
- index-url:指定PyPI的基路径。
- find-links :设置package所在的路径,如果url执行html文件那么解析这个文件,如果url是"file://"那么在url指定目录的文件列表里查找。
- no-index:忽略index,只在find-links时使用。
- ignore-installed:强制安装,即便已经安装了。
- no-deps:忽略依赖关系。
导入python自带包或外部包
Python自带包可以直接用import package或者from package import module来进行导入,以为自带包都存在于系统包路径中,可以通过sys.path来查看:
第三方python包路径需要添加到sys.path或者复制到已有sys.path中才可以正常导入。使用sys.path.append(“path_to_third_party_packages”)进行添加
出现ImportError: No module named 'xxx’问题
先考虑4个问题:
- 包是否为有效的包(用__init__.py标识)
- 包的路径在哪?是否添加到sys.path?
- 包中是否有要导入的模块
- 包的__init__.py中__all__是否包含要使用的模块(针对用from package import *导入的情况)
包安装后,使用python –m pip show package获取的路径信息与实际安装的包并不一致
比如python -m pip show pyserial获取的pyserial路径在下图:
然而在交互解释器导入,
只能导入serial,实际上serial就是pyserial的一部分
关于 python ImportError: No module named 'xxx’的问题?
解决方法如下:
-
使用PYTHONPATH环境变量,在这个环境变量中输入相关的路径,不同的路径之间用逗号
(英文的!)分开,如果PYTHONPATH 变量还不存在,可以创建它!这里的路径会自动加入到sys.path中,永久存在于sys.path中而且可以在不同的python版本
中共享,应该是一样较为方便的方法。
C:\Users\Administrator\Desktop\test\module1.py:
def func1():
print(“func1”)将C:\Users\Administrator\Desktop\test添加到PYTHONPATH即可直接import module1,然后
调用:module1.func1()即可。 -
将自己做的py文件放到 site_packages 目录下
-
使用pth文件,在 site-packages 文件中创建 .pth文件,将模块的路径写进去,一行一
个路径,以下是一个示例,pth文件也可以使用注释:# .pth file for the my project(这行是注释),命名为xxx.pth文件 C:\Users\Administrator\Desktop\test
这个不失为一个好的方法,但存在管理上的问题,而且不能在不同的python版本中共享。
-
列表内容
在调用文件中添加sys.path.append(“模块文件目录”);
-
直接把模块文件拷贝到$python_dir/Lib目录下。
通过以上5个方法就可以直接使用import module_name了。
参考文章:http://my.oschina.net/leejun2005/blog/109679
导入规则
https://blog.youkuaiyun.com/minghu9/article/details/50828903
help查看包、模块、函数、类的注释
pathon内置的模块和第三方包一般都会有说明,这些说明在代码里的体现形式即是字符串形式的注释(另一种是以#开头直到行结束为注释),可以在模块和类的开头、在函数def语句的后面。
函数字符串
函数字符串
放在函数开头的字符串成为文档字符串(docstring),将作为函数的一部分存储起来,如下所示:
def square(x):
'Calculates the square of the number x.'
return x * x
可以像下面这样访问文档字符串:
>>> square.__doc__
'Calculates the square of the number x.'
注意__doc__是函数的一个属性。属性名中的双下划线表示这是一个特殊的属性。
使用help()获取函数信息,其中包含函数的文档字符串:
>>> help(square)
Help on function square in module __main__:
square(x)
Calculates the square of the number x.
内置函数help
注意,在交互式解释器使用包或者模块前,首先import导入。
当然,也可以不导入,在help()参数中使用单引号方式,例子如下:
查看python所有的modules:help(“modules”)
查看.py结尾的普通模块help(module_name)
单看python所有的modules中包含指定字符串的modules: help(“modules yourstr”)
查看python中常见的topics: help(“topics”)
查看python标准库中的module:import os.path + help(“os.path”)
查看python内置的类型:help(“list”)
查看python类型的成员方法:help(“str.find”)
查看python内置函数:help(“open”)
获取函数信息
>>> help(copy.copy)
Help on function copy in module copy:
copy(x)
Shallow copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
上述函数帮助信息指出,copy只接受1个参数x,执行的是浅复制,提到的__doc__字符串也即函数开头写的用于说明函数的“文档字符串”,实际上copy()函数打印的信息,部分也是从函数copy的文档字符串中提取的:
>>> print(copy.copy.__doc__)
Shallow copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
相比于直接查看文档字符串,使用help的优点是可获取更多的信息,如函数的特征标(即它接受的参数)
获取包信息
包信息不近包括__init__.py开头的注释,还有python包规定的特殊变量如__version__,包名称NAME,包含有的模块PACKAGE CONTENTS,公用函数FUNCTIONS,变量DATA,包版本VERSION,init.py 路径FILE
>>> import serial
>>> help(serial)
Help on package serial:
NAME
serial
DESCRIPTION
# This is a wrapper module for different platform implementations
#
# This file is part of pySerial. https://github.com/pyserial/pyserial
# (C) 2001-2017 Chris Liechti <cliechti@gmx.net>
#
# SPDX-License-Identifier: BSD-3-Clause
PACKAGE CONTENTS
。。。。。。。。。。
FUNCTIONS
。。。。。。。。。。
DATA
。。。。。。。。。。
VERSION
3.4
FILE
c:\users\administrator\appdata\local\programs\python\python36\lib\site-packages\serial\__init__.py
获取模块信息
>>> import serial
>>> from serial import rs485
>>> help(serial.rs485)
Help on module serial.rs485 in serial:
NAME
serial.rs485
DESCRIPTION
The settings for RS485 are stored in a dedicated object that can be applied to
serial ports (where supported).
NOTE: Some implementations may only support a subset of the settings.
获取类信息
>>> from serial.rs485 import RS485
>>> help(serial.rs485.RS485)
Help on class RS485 in module serial.rs485:
class RS485(serial.serialwin32.Serial)
| A subclass that replaces the write method with one that toggles RTS
| according to the RS485 settings.
|
| NOTE: This may work unreliably on some serial ports (control signals not
| synchronized or delayed compared to data). Using delays may be
| unreliable (varying times, larger than expected) as the OS may not
| support very fine grained delays (no smaller than in the order of
| tens of milliseconds).
pydoc的用法
pydoc模块可以从python源码文件中获取docstring,然后生成帮助信息。
纯文本帮助信息
如在控制台输入命令 pydoc string 则会在控制台生成string的纯文本帮助信息。
root@ubuntu:/home/lvjc/myPython# pydoc string
Help on module string:
NAME
string - A collection of string operations (most are no longer used).
FILE
/usr/lib/python2.7/string.py
HTML帮助信息
pydoc还可以生成HTML格式的帮助信息,可以将HTML帮助信息生成到静态文本中,也可以启动一个Web服务器在线浏览帮助文档。
root@ubuntu:/home/lvjc/myPython# pydoc -w string //在当前目录创建string.html文件
root@ubuntu:/home/lvjc/myPython# pydoc -p 5000 //启动一个web服务器监听 http://localhost:5000/