模块
导入模块
导入整个模块
# 导入整个模块。
import math
print(math.log2(8)) # 这种导入方式需要使用 模块名.方法() 来调用
导入模块中特定的方法或类
# 导入模块中的指定方法。
from math import log2,log10
print(log2(8)) # 这种导入方式可以直接使用方法名来调用
print(log10(100))
导入模块中所有方法和类
# 导入 math 模块中的全部方法,使用和上面一致,直接使用方法名(不建议,容易出现命名冲突)
from math import *
print(log2(8))
给导入的方法取别名
# 给方法取别名
from math import log2 as l2g,log10 as l10g
print(l2g(8))
print(l10g(100))
给导入的模块取别名
# 给模块取别名
import math as m
print(m.log2(8))
标准库
Python 自带了许多标准库模块,这些模块提供了广泛的功能,从文件操作到网络编程,再到数据处理等。以下是一些常用的标准库模块:
os
:提供了与操作系统交互的功能,如文件路径操作、环境变量等。sys
:提供了与 Python 解释器交互的功能,如命令行参数、退出程序等。math
:提供了数学运算函数,如平方根、三角函数等。datetime
:提供了日期和时间处理的功能。random
:提供了生成随机数的功能。json
:提供了处理 JSON 数据的功能。
自定义模块
自定义一个模块 my_module.py(也就是新建一个 py 文件,一个文件就是一个模块):
__all__
:规定哪些内容可以被导入,比如这个模块的multiply
就不允许被导入(只能限制 from 的导入方式)__name__
:用来测试模块功能的,导入模块内容其实是把导入的内容加载(运行)一次。__name__
的内容不会加载
# sum 和 multiply 方法可以被导入
__all__ = ["sum"]def sum(a: int, b: int) -> int:return a + bdef multiply(a: int, b: int) -> int:return a * b# 测试模块
if __name__ == '__main__':print(sum(1, 2))print(multiply(1, 2))
使用自定义的模块 eg1:
from my_module import *print(sum(1, 2)) # 输出 3
print(multiply(1, 2)) # 报错,这个方法不允许导入
使用自定义的模块 eg2:
import my_module as mmprint(mm.sum(1, 2)) # 输出 3
print(mm.multiply(1, 2)) # 输出 2(__all__ 只能限制 from 的导入方式,直接 import 的导入方式限制不了)
包
包(Package)是 Python 中用于组织模块的一种方式。它允许你将多个模块组织在一个目录中,并通过层次化的命名空间来管理这些模块。包的使用使得代码结构更加清晰,特别适合大型项目。
什么是包?
- 包是一个包含
__init__.py
文件的目录。这个文件可以是空的,也可以包含包的初始化代码。 - 包中可以包含多个模块(
.py
文件)或子包(子目录)。
例如,一个包的目录结构可能如下:
mypackage/ # 包名__init__.py # 包的初始化文件module1.py # 模块1module2.py # 模块2subpackage/ # 子包__init__.py # 子包的初始化文件module3.py # 子包中的模块
创建包
基本结构
- 创建一个目录,目录名就是包名(如
mypackage
)。 - 在该目录下创建一个
__init__.py
文件(可以是空的)。 - 在包目录中创建模块文件(如
module1.py
、module2.py
)。
示例
假设我们创建一个名为 mypackage
的包:
mypackage/__init__.pymodule1.pymodule2.py
-
module1.py
内容:def greet(name):return f"Hello, {name}!"
-
module2.py
内容:def add(a, b):return a + b
导入包
导入整个包
import mypackage
print(mypackage.module1.greet("Alice")) # 使用模块1中的函数
print(mypackage.module2.add(2, 3)) # 使用模块2中的函数
导入包中的特定模块
from mypackage import module1
print(module1.greet("Bob")) # 直接使用 module1 中的函数
导入包中的特定函数
from mypackage.module2 import add
print(add(5, 7)) # 直接使用 add 函数
使用 __init__.py
简化导入
如果在包的 __init__.py
文件导入了模块的函数或类,如下:
from .module1 import greet
from .module2 import add
可以直接从包中导入类会函数:
from mypackage import greet, add
print(greet("Charlie")) # 直接使用 greet 函数
print(add(10, 20)) # 直接使用 add 函数
子包
包可以嵌套,形成子包。子包也是一个目录,包含自己的 __init__.py
文件和模块。
例如:
mypackage/__init__.pymodule1.pysubpackage/__init__.pymodule3.py
-
module3.py
内容:def multiply(a, b):return a * b
导入子包中的模块
from mypackage.subpackage import module3
print(module3.multiply(3, 4)) # 输出 12
从子包中导入特定函数
from mypackage.subpackage.module3 import multiply
print(multiply(5, 6)) # 输出 30
__init__.py
的作用
- 标识目录为包:Python 通过
__init__.py
文件识别一个目录是否为包。 - 初始化包:可以在
__init__.py
中编写包的初始化代码。 - 简化导入:通过在
__init__.py
中导入模块的函数或类,用户可以更方便地使用包的功能。
例如,在 mypackage/__init__.py
中:
from .module1 import greet
from .module2 import add
from .subpackage.module3 import multiply
用户可以直接从包中导入:
from mypackage import greet, add, multiply
print(greet("Alice")) # Hello, Alice!
print(add(2, 3)) # 5
print(multiply(4, 5)) # 20
包的相对导入
在包内部,可以使用相对导入来引用其他模块或子包。相对导入使用 .
表示当前目录,..
表示上级目录。
例如,在 mypackage/subpackage/module3.py
中:
from ..module1 import greet # 从上级目录导入 module1 中的 greet 函数
包的发布与安装
如果你希望将自己的包分享给他人使用,可以将包发布到 PyPI(Python Package Index),或者直接打包成可安装的文件。
打包工具
setuptools
:用于定义包的元数据和依赖。wheel
:用于生成.whl
格式的包文件。
打包步骤
-
在包目录下创建
setup.py
文件:from setuptools import setup, find_packagessetup(name="mypackage",version="0.1",packages=find_packages(),install_requires=[], # 依赖的其他包 )
-
生成分发文件:
python setup.py sdist bdist_wheel
-
上传到 PyPI:
twine upload dist/*
-
安装包:
pip install mypackage
PIP
pip 是 Python 用来安装三方包(模块或库)的工具,类似 java 的 maven 或 node 的 npm
Python2 的 2.7.9+ 版本和 Python3 的 3.4+ 版本已经内置了 pip
Python2 使用 pip
Python3 使用 pip3
常用命令
pip3 install package_name # 安装包,不指定版本(默认最新版本)
pip3 install package_name==version # 指定版本安装包
pip3 install --upgrade package_name # 升级包
pip3 uninstall package_name # 卸载包
pip3 list # 查看已安装的包
pip3 show package_name # 查看某个已安装包的详细信息
pip3 search package_name # 搜索包
pip3 search
已经被弃用,如果要在终端使用,需要安装 pip-search
或 pip-simple
官方推荐到网站上搜索,然后用命令安装,官方网址 https://pypi.org/search
命令使用示例
pip3 install requests # 安装 requests
pip3 install requests==2.25.1
pip3 install --upgrade requests # 升级
pip3 uninstall requests # 卸载
pip3 show requests # 查看详细信息
pip3 install requests -i https://pypi.tuna.tsinghua.edu.cn/simple # 默认是从 pypi.org 下来
镜像源
pip3 config list # 查看当前镜像源(没配置过就是空,会到 pypi.org 去下载)
pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/ # 设置镜像地址为 阿里源
pip3 config set global.trusted-host mirrors.aliyun.com # 信任阿里源的域名
pip3 config unset global.index-url # 回复默认镜像源地址
- 清华大学:
https://pypi.tuna.tsinghua.edu.cn/simple
- 阿里云:
https://mirrors.aliyun.com/pypi/simple/
- 豆瓣:
https://pypi.douban.com/simple/
- 华为云:
https://repo.huaweicloud.com/repository/pypi/simple/
如果信任了自己配置的源,还是报错:
ERROR: XMLRPC request failed [code: -32500]
RuntimeError: PyPI no longer supports 'pip search' (or XML-RPC search). Please use https://pypi.org/search (via a browser) instead. See https://warehouse.pypa.io/api-reference/xml-rpc.html#deprecated-methods for more information
那就是证书问题了,我的是 mac 解决方案如下:
pip3 install certifi # 安装证书
python3 -m certifi # 得到证书地址
vim ~/.zhsrc # 证书配置到环境变量中(我用的 zsh),保存文件,然后刷新一下 source ~/.zshrc 就好了
source ~/.zshrc## 我的 .zhsrc 如下
# java 17
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
export PATH=${JAVA_HOME}/bin:$PATH# java 8
#export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home
#export PATH=${JAVA_HOME}/bin:$PATH# maven 3.9.9
export MAVEN_HOME=/Users/cyrus/MyApp/maven/apache-maven-3.9.9
export PATH=${MAVEN_HOME}/bin:$PATH# pip3 证书
export SSL_CERT_FILE=/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/certifi/cacert.pemsource /Users/cyrus/.dacs_run_profile