模块


模块

函数可以复用代码。如果想复用一系列的函数怎么办?如你所想,答案就是模块。
有很多写模块的方法,但是最简单的还是创建一个后缀为.py的文件,然后在里面写上函数和变量。
另一种写模块的方法:用本地语言(用来写Python解释器的语言)写模块。比如说,你可以用c语言来写模块,经过编译后,你就可以通过Python解释器使用它了。
其它程序可以导入模块,然后使用模块里的功能。就如我们使用Python的标准库一样。首先,我们学习如何使用标准库里的模块。
例子(保存至module_using_sys.py):

import sys

print('命令行参数:')
for arg in sys.argv:
    print(arg)

print('PYTHON_PATH:', sys.path)

输出:

$ python module_using_sys.py we are arguments
命令行参数:
module_using_sys.py
we
are
arguments
PYTHON_PATH: [.......]
它是怎么运作的呢?

我们先是用import语句导入sys模块,告诉Python,我们想要使用这个模块。sys模块包含关于Python解释器和Python环境的功能。
当Python执行import sys时,先是寻找sys模块。因为sys模块是内置的,因此Python肯定知道在哪里能够找到它。
如果不是编译好的模块,而是用Python写的模块呢?Python解释器会搜索一些目录,去找要导入的模块。这些目录就是sys.path的列表。如果模块找到了,模块里的代码就会被执行,此刻开始,模块就生效了。注意,只有第一次导入一个模块的时候,才会有上述的初始化过程。
sys模块里的argv变量,可以用.后缀获取到,也就是sys.argv。用这种点号后缀方式,清晰地表现出变量argv属于sys模块。这种方式另外一个优点就是程序里的名字不会发生冲突。
sys.argv变量表示一个字符串列表。进一步讲,sys.argv包含命令行的参数值,也就是,在输入执行程序的命令时,传入的参数值。
如果你正在用IDE写程序,运行程序,在菜单栏找到可以输入命令行参数的选项。
当执行python module_using_sys.py we are arguments时,只有python是命令,其它都是参数值,它们将会被保存到sys.argv变量里。
记住,运行的脚本名字是参数值列表的第一个元素。所以在本例中,sys.argv[0]可以表示module_using_sys.py。sys.argv[1]表示we,sys.argv[2]表示are,sys.argv[3]表示arguments。注意,Python从0开始计数。
sys.path包含一个目录列表,这些目录用来放置模块。可以看到,sys.path的列表的第一个元素是一个空字符串,它用来表示当前目录。也就是说,你可以直接导入当前目录里的模块。其他情况下,你需要把模块放到sys.path列表中目录的一个。
注意,当前目录就是执行程序时用户所在的目录。你可以导入os模块,然后输入print(os.getcwd())来找出当前目录。


byte-compiled .pyc文件

导入模块的开销是挺大的,因此Python有一些技巧可以让它更快。创建byte-compiled文件(后缀为.pyc)就是其中之一。byte-compiled文件是Python执行程序时产生的中间代码。这种文件在多个程序导入相同的模块时很有用,因为导入模块的一些处理过程被跳过了。同样,这些文件各个平台都不一样。
注意:这些.pyc文件一般生成在对应.py文件所在的目录。如果Python在该目录没有写的权限,那么.pyc文件无法被创建。


from...import语句

如果想直接导入argv变量到你的程序里(不用每次都在前面加上sys.),你可以使用from sys import argv语句。

警告:
一般要避免使用from ... import语句,因为它会增加名冲突的倾向,而且让程序更难阅读。

例子

from math import sqrt
print('16的平方根', sqrt(16))

模块属性name

每个模块都有一个名字。在一个模块里,可以用语句去找到所用模块的名字。这个在查看模块是作为脚本在运行,还是被导入时相当有用。当一个模块初次被导入,模块内的代码被执行。模块作为脚本运行和被导入的表现会有所差异。模块的name会有所不同,就是其中之一。
例子(保存至module_using_name.py):

if __name__ == '__main__':
    print('独自运行')
else:
    print('被导入')

输出:

$ python module_using_name.py
独自运行
$ python
>>> import module_using_name
被导入
它是怎么运作的呢?

每一个模块都会定义name变量。如果它被赋值__main__,就表示模块作为脚本在运行,这个时候你就可以搞点事了。


创建模块

创建模块很简单,你一直都在创建模块。因为,在Python中每一个程序都是一个模块。你只要让Python程序带有.py后缀就可以了。
例子(保存至mymodule.py):

def say_hi():
    print('哎,这就是模块?')

__version__ = '0.1'

这是一个模块样例。所以,模块和我们通常写的程序并没有什么不同。下面将讲解怎么在程序中使用模块。
记住,模块应该放在程序运行的目录,或者sys.path列表中的某个目录。
另外一个例子(保存至mymodule_demo.py):

import mymodule
mymodule.say_hi()
print('版本', mymodule.__version__)

输出:

$ python mymodule_demo.py
哎,这就是模块?
版本 0.1
它是怎么运作的呢?

注意,我们使用点号去获取模块的成员。Python会在相似的场合下复用某种符号,所以你不用去学习新的方式去完成任务,这种风格被称为pythonic
下面是使用from ...import的版本(保存至mymodule_demo2.py):

from mymodule import say_hi, __version__

say_hi()
print('版本', __version__)

输出与运行mymodule_demo.py的一样。
注意,假设某个模块有version名,如果再用from...import导入version会发生名冲突。这种情况很有可能发生,因为通常都是用version用作版本号。因此,推荐使用import语句而不是使用from...import。
你也可以这样写:

from mymodule import *

这种情况会导入所有的公共名,但是以双下滑线开始的名不会被导入。
警告:
你应该避免使用import *。

Python的禅:
一个Python的准则是:明确的比隐晦的好。


dir函数

内置的dir函数返回一个对象的名列表。如果对象是一个模块,这个列表会包含在其中定义的函数,类和变量。
这个函数接受参数值。如果参数是一个模块的名,函数会返回一个模块内名的列表。如果没有传如参数值,函数返回当前模块的名列表。
例子:

$ python
>>> import sys
>>> dir(sys)
['__displayhook__',
'__doc__',
...,
]
>>> dir()
['__builtins__',
'__doc__',
...,
]
>>> a = 5
>>> dir()
['__builtins__',
'__doc__',
'sys',
'a',
...,
]
>>> del a
>>> dir()
['__builtins__',
'__doc__',
...,
]
它是怎么运作的呢?

我们先是向dir传入sys名。可以看到sys模块包含了很多属性。
接下来,不给dir传参数值。默认情况,它会返回当前模块的所有属性。注意,导入的模块也会出现在列表里。
为了观察dir的特性,我们定义了一个变量,并给它赋值,然后查看dir的结果,发现新增了一个同变量同名的元素。当使用del把变量从当前模块移除后,dir打印出的结果中发生了相似的现象。
del的小提示:该语句用来删除变量或名,在语句被执行后,例子中的a变量被删除了。你不再能访问a变量了,就好象之前没有存在过。
注意,dir函数可以传入任意对象名。举个栗子,执行dir(str)会返回str类的所有属性。
有一个vars()函数,会给出对象的属性和它的值,但是它在某些情况下不起效。

--

--

你肯定观察到了程序是有层次的。变量一般在函数里定义。函数和全局变量一般定义在模块里。那么怎么组织模块呢?答案就是包。
包就是包含模块的文件夹,但是它会包含一个特殊的文件 - __init__.py。这个文件用来告知Python,该文件夹是一个包。
下面开始创建一个叫做world的包,在里面包含asia包、africa包等等。这些子包包含一些模块,像indiamadagascar等等。
下面是目录结构:

world/
    __init__.py
    asia/
        __init__.py
        india/
            __init__.py
            foo.py
    africa/
        __init__.py
        madagascar/
            __init__.py
            bar.py

用包来组织模块很便捷。你在标准库里可以看到很多例子。


总结

待续。。。

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

推荐阅读更多精彩内容

  • 用 python 解释器来编程从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。 为此...
    chen_000阅读 510评论 0 3
  • 目录: 上一节课生成器还有一些知识点没讲到,接下来补充; 一、协程函数 生成器:yield关键字的另外一种用法yi...
    CaiGuangyin阅读 536评论 0 1
  • 模块是最高级别的程序组织单元,它将程序代码和数据封装起来以便重用。 模块是变量名的封装,被认为是命名空间。模块导入...
    lakerszhy阅读 482评论 0 2
  • 类 类的概念在许多语言中出现,很容易理解。它将数据和操作进行封装,以便将来的复用。 模块 模块,在Python可理...
    随风化作雨阅读 1,885评论 0 5
  • 小升初陪读记九 我做好了准备,好好陪孩子一年,给予高质量的陪伴。可是,这中间情绪还是会有些波动。这个工作没有什么成...
    李云扬阅读 436评论 4 8