python笔记-模块

世人都说不要重复造轮子,但学习阶段,自己造些轮子,还是很有用的.

模块是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用。

创建自己的模块时,要注意:

  • 模块名要遵循Python变量命名规范,不要使用中文、特殊字符;
  • 模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。
  • 另外注意函数名不要和内置函数重名

包(package)

为了避免模块名冲突,python引入了按目录来组织模块的方法,称为包(package)

一个abc.py文件就是一个名叫abc的模块,一个xyz.py文件就是一个名字叫xyz的模块,假设这两个模块于其他模块冲突了,此时可以通过来避免,只要加一个顶层包名,比如mycompany,按照如下目录存放:

1
2
3
4
mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py

其中每一个包目录下面都要有一个__init__.py文件,这个文件是必须的,里面可以是空文件,也可以有代码,因为__init__.py本身就是一个模块,它的模块名就是mycompany

另外可以有多级目录,组成多层次的包结构,每一层都要有__init__.py

1
2
3
4
5
6
7
8
mycompany
├─ web
│ ├─ __init__.py
│ ├─ utils.py
│ └─ www.py
├─ __init__.py
├─ abc.py
└─ utils.py

文件www.py的模块名就是mycompany.web.www,两个文件utils.py的模块名分别是mycompany.utilsmycompany.web.utils

使用模块

使用

1
2
3
import xxx
import xxx as xx
from xxx import xx

安装

  1. pip
    一般来说第三方库都会在官方的pypi.python.org注册,通过pip命令即刻安装

    1
    pip install requests
  2. Anaconda

    Anaconda会把系统Path中的python指向自己自带的Python,并且,Anaconda安装的第三方模块会安装在Anaconda自己的路径下,不影响系统已安装的Python目录.

    另外,用Anaconda管理虚拟环境也是很好的选择.

模块搜索路径

默认下,python会搜索当前目录,所有已安装的内置模块第三方模块,搜索路径存放在sys模块的path变量中

1
2
3
4
5
6
7
8
import sys
sys.path
> ['/opt/python3/bin',
'/opt/python3/lib/python310.zip',
'/opt/python3/lib/python3.10',
'/opt/python3/lib/python3.10/lib-dynload',
'',
'/opt/python3/lib/python3.10/site-packages']

修改搜索路径,添加自己的目录有两种方法:

  1. 在代码中修改sys.path,这种方法只会在代码运行时有效

    1
    2
    import sys
    sys.path.append('/Users/michael/my_py_scripts')
  2. 修改环境变量PYTHONPATH,该变量的内容会添加到原有的搜索路径中,原来的搜索路径不受影响.

模块编写

hello模块为例,展示标准的模块模板:

hello.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys # 导入sys模块后,就有了sys这个变量指向sys模块

def test():
args = sys.argv # sys有一个argv变量,用list存储命令所有参数,第一个参数永远是运行的.py文件文件名
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')

if __name__=='__main__':
test()
  • 第一行是标准注释,表明使用哪个python运行时
  • 第二行也是标准注释,表明.py文件本身使用标准的UTF-8编码
  • 第四行是一个字符串,任何模块代码的第一个字符串都被视为模块的文档注释
  • __author__变量表示模块作者
  • 后面才是你的代码

注意这两行代码:

1
2
if __name__=='__main__':
test()

当我们在命令行运行hello模块文件时,python解释器会把一个特殊的变量__name__赋值为__main__,

而如果在其他地方导入该模块,if判断会失效,

所以这种if可以让一个模块通过命令行运行时执行一些额外的代码.用作运行测试.

1
2
3
4
5
6
7
8
9
# 在命令行运行
python hello.py Peter
> Hello, Peter!

# 导入时,没有任何输出
import hello
# 只有调用里面的函数才会执行代码
hello.test()
> Hello world!

作用域

__xxx__是特殊变量,可以被直接引用,是public的,比如__author__,__name__等,模块定义的文档注释也可以用__doc__访问,我们自己代码一般不要用这种变量名

  • 正常的函数名和变量是公开的public,可以被直接引用
  • 非公开的private函数名和变量以_前缀来表示,比如_xxx__xxx.他们都不应该被直接引用
    • python并没有一种方法可以完全限制private函数或变量的访问,但是从编程习惯上我们不应该应用private函数或变量
1
2
3
4
5
6
7
8
9
10
11
def _private_1(name):
return 'Hello, %s' % name

def _private_2(name):
return 'Hi, %s' % name

def greeting(name):
if len(name) > 3:
return _private_1(name)
else:
return _private_2(name)

例如上面的代码,只公开了greeting函数,内部逻辑都用private函数隐藏起来.这样在调用greeting()时就不需要关心内部的provate函数细节,这是一种非常有用的代码封装和抽象的方法.


python笔记-模块
http://example.com/2024/01/10/python-module/
作者
Peter Pan
发布于
2024年1月10日
许可协议