使用模块
Python 本身就内置了很多非常有用的模块, 只要安装完毕, 这些模块就可以立刻使用.
我们以内建的 sys 模块为例, 编写一个 hello 的模块:
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- 'a test module'
- _author_ = 'Micheal Liao'
- import sys
- def test():
- args = sys.argv
- if len(args)==1:
- print('Hello, world!')
- elif len(args)==2:
- print('Hello,%s!'% args[1])
- else:
- print('too many')
- if __name__=='__main__':
- test()
第 1 行和第 2 行是标准注释, 第 1 行注释可以让这个 hello.py 文件直接在 Unix/Linux/Mac 上运行, 第 2 行注释表示. py 文件本身使用标准 UTF-8 编码;
第 4 行是一个字符串, 表示模块的文档注释, 任何模块代码的第一个字符串都被视为模块的文档注释;
第 6 行使用__author__变量把作者写进去, 这样当你公开源代码后别人就可以瞻仰你的大名;
以上就是 Python 模块的标准文件模板, 当然也可以全部删掉不写, 但是, 按标准办事肯定没错.
后面开始就是真正的代码部分.
你可能注意到了, 使用 sys 模块的第一步, 就是导入该模块:
import sys
导入 sys 模块后, 我们就有了变量 sys 指向该模块, 利用 sys 这个变量, 就可以访问 sys 模块的所有功能.
sys 模块有一个 argv 变量, 用 list 存储了命令行的所有参数. argv 至少有一个元素, 因为第一个参数永远是该. py 文件的名称, 例如:
运行 python hello.py 获得的 sys.argv 就是['hello.py'];
运行 python hello.py Michael 获得的 sys.argv 就是['hello.py', 'Michael].
最后, 注意到这两行代码:
- if __name__ ='__mian__'
- test()
当我们在命令行运行 hello 模块文件时, Python 解释器把一个特殊变量__name__置为__main__, 而如果在其他地方导入该 hello 模块时, if 判断将失败, 因此, 这种 if 测试可以让一个模块通过命令行运行时执行一些额外的代码, 最常见的就是运行测试.
我们可以用命令行运行 hello.py 看看效果:
- $ python hello.py
- Hello, world!
- $ python hello.py Michael
- Hello, Michael!
如果启动 Python 交互环境, 再导入 hello 模块:
这里如果我改名为 hello2 那么就是导入 hello2 模块 导入模块名称 = 文件名
- >>> import hello
- >>> hello.test
- <function test at 0x061475D0>
- >>> hello.test()
- Hello, world!
导入时, 没有打印 Hello, Word!, 因为没有执行 test()函数.
调用 hello.test()时, 才能打印出 Hello, Word!:
别名
导入模块时, 还可以使用别名, 这样, 可以在运行时根据当前环境选择最合适的模块. 比如 Python 标准库一般会提供 StringIO 和 cStringIO 两个库, 这两个库的接口和功能是一样的, 但是 cStringIO 是 C 写的, 速度更快, 所以, 你会经常看到这样的写法:
- try:
- import cStringIO as StringIO
- except ImportError: # 导入失败会捕获到 ImportError
- import StringIO
这样就可以优先导入 cStringIO. 如果有些平台不提供 cStringIO, 还可以降级使用 StringIO. 导入 cStringIO 时, 用 import ... as ... 指定了别名 StringIO, 因此, 后续代码引用 StringIO 即可正常工作.
还有类似 simplejson 这样的库, 在 Python 2.6 之前是独立的第三方库, 从 2.6 开始内置, 所以, 会有这样的写法:
- try:
- import JSON # python>= 2.6
- except ImportError:
- import simplejson as JSON # python <= 2.5
由于 Python 是动态语言, 函数签名一致接口就一样, 因此, 无论导入哪个模块后续代码都能正常工作.
作用域
在一个模块中, 我们可能会定义很多函数和变量, 但有的函数和变量我们希望给别人使用, 有的函数和变量我们希望仅仅在模块内部使用. 在 Python 中, 是通过_前缀来实现的.
正常的函数和变量名是公开的(public), 可以被直接引用, 比如: abc,x123,PI 等;
类似__xxx__这样的变量是特殊变量, 可以被直接引用, 但是有特殊用途, 比如上面的__author__,__name__就是特殊变量, hello 模块定义的文档注释也可以用特殊变量__doc__访问, 我们自己的变量一般不要用这种变量名;
类似_xxx 和__xxx 这样的函数或变量就是非公开的(private), 不应该被直接引用, 比如_abc,__abc 等;
之所以我们说, private 函数和变量 "不应该" 被直接引用, 而不是 "不能" 被直接引用, 是因为 Python 并没有一种方法可以完全限制访问 private 函数或变量, 但是, 从编程习惯上不应该引用 private 函数或变量.
private 函数或变量不应该被别人引用, 那它们有什么用呢? 请看例子:
- def _private_1(name):
- return ('Hello, %s' % name)
- def _privare_2(name):
- return('Hi, %s' % name)
- def greeting(name):
- if len(name)>3:
- return _private_1(name)
- else:
- return _private_2(name)
运行一下
- >>> greeting('o')
- 'Hi, o'
- >>> greeting('lida')
- 'Hello, lida'
我们在模块里公开 greeting()函数, 而把内部逻辑用 private 函数隐藏起来了, 这样, 调用 greeting()函数不用关心内部的 private 函数细节, 这也是一种非常有用的代码封装和抽象的方法, 即:
外部不需要引用的函数全部定义成 private, 只有外部需要引用的函数才定义为 public.
PS:
一些小问题的介绍
Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from module import'导入 xxx 系统定义名字 xxx 类中的私有变量名 核心风格: 避免用下划线作为变量名的开头. 因为下划线对解释器有特殊的意义, 而且是内建标识符所使用的符号, 我们建议程序员避免用下划线作为变量名的开头. 一般来讲, 变量名_xxx 被看作是 "私有的", 在模块或类外不可以使用. 当变量是私有的时候, 用_xxx 来表示变量是很好的习惯. 因为变量名 xxx__对 Python 来说有特殊含义, 对于普通的变量应当避免这种命名风格. "单下划线" 开始的成员变量叫做保护变量, 意思是只有类对象和子类对象自己能访问到这些变量; "双下划线" 开始的是私有成员, 意思是只有类对象自己能访问, 连子类对象也不能访问到这个数据. 以单下划线开头 (如_foo) 的代表不能直接访问的类属性, 需通过类提供的接口进行访问, 不能用 "from xxx import" 而导入; 以双下划线开头的 (如 foo) 代表类的私有成员; 以双下划线开头和结尾的 (foo) 代表 python 里特殊方法专用的标识, 如 init__() 代表类的构造函数. 摘自: https://www.cnblogs.com/MUMO/p/5718578.html
python 学习之路(22)
来源: http://www.bubuko.com/infodetail-3066425.html