3418 字
17 分钟
python基础

官网 | 文档

模块#

示例:

# 1. 模块的文档字符串
"""
module1
这个模块提供的功能
作者
时间等元数据
"""
# 2. 变量 (Variables)
a=1
# 3. 常量 (Constants) - Python中没有真正的常量,但约定大写表示常量
PI =3.14
# 4. 函数 (Functions)
def add(a,b):
return a+b
# 5. 类 (Classes)
class Student:
def __init__(self, name=None, age=None):
self._name = name
self._age = age
@property#相当于get方法
def age(self):
return self._age
@age.setter#set方法
def age(self, value):
self._age = value
# 6.模块的主函数
import sys
print(f"__name__ = {__name__}")
#如果是直接运行这个模块的话,__name__就是__main__,
#如果是被调用的话,__name__是这个模块的名字。
if __name__ == "__main__":
print("这个只有在这个模块被直接运行的时候才会执行")
print(__doc__)#打印这个模块的文档字符串

#

包是包含多个模块的目录,包含__init__.py文件。

项目结构
project/
├── package1/
│ ├── __init__.py
│ ├── module2.py
│ └── module3.py
├── package2/
│ ├── __init__.py
│ ├── package1/
│ │ ├── __init__.py
│ │ └── moudle4.py
│ └── module5.py
├── module1.py
└── main.py
package1/__init__.py
#显示表示这个包里有什么模块,这两个模块会放在package1的命名空间中
from . import module2
from . import module3
#init文件里可以写当这个包被调用时的函数,多次import这个包不会重复执行init文件里的主函数
print("package1初始化文件被执行")
#当然也能写包的函数,变量,常量,会进入到包的命名空间
def add(a,b):
return a+b
#如果__init__.py里的命名和模块名重了,那么保留__init__.py里自带的,上面导入的模块将无法使用
def module2(a,b):#p1.module2将不会指定到module2模块,而是这个函数
return a+b
from .module2 import add,PI
# 控制主函数 from package import * 引入的东西
__all__ = ['add']#只引的进add

导入#

main.py
#导入整个模块,主函数命名空间dir()只有module1(模块名)被占用
import module1
a=module1.a
# 从模块导入特定内容,主函数命名空间dir(),只有被import的命名会被占用,如果是*的话会把所有的module里的命令引入过来
from module1 import a, add
a=add(1,2)
#如果使用了as那就只会把as后的名称进入命名空间
import numpy as np
#不能使用numpy只能用np
import package1.module2#package1被导入到主函数命名空间,module1被导入package1的命名空间,即使没用__init__.py也行
#会被包的__all__控制
from package1 import *

包管理#

这两个视频非常重要,算是工程应用包管理的核心一步了,不看不行。可以去底下那些库里看一下大部分开源项目的项目结构。

pip#

Terminal window
pip list
# 生成环境库的列表
pip freeze > requirements.txt
#把requirements.txt里的依赖全安装下来
pip install -r requirements.txt

但是requirements.txt混合了所有直接和间接依赖, 所以现代配置依赖以及管理项目元数据使用pyproject.toml

[project]
name = "simple-project"
version = "0.1.0"
description = "一个简单的Python项目"
authors = [{name = "Your Name"}]
dependencies = [
"requests>=2.25.0",
"click>=8.0.0",
]
[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"

使用pip安装.toml文件中的所有依赖

Terminal window
pip install -e .
#-e代表编辑模式可以把自己的项目作为一个依赖放在依赖路径中,调用时可以当正常依赖调用

uv#

Terminal window
#列出所有可用的python版本,freetreaded实验版本不要用。
uv python list
#安装python
uv python install [可选版本]
#可以直接py脚本可以是python本身,进入对应版本的python解释器。如果没装过你指定的那个版本就会自动给你安装
#后面-p <python版本>可以不写,toml文件中指定了版本,他就会自动调用那个版本,没指定就用已安装的最新的。
#运行时自动进入该项目的虚拟环境
uv run [-p <python版本>] <py脚本>
#还可以运行python本身
uv run python
#还可以运行ruff等工具
uv tool run [已安装的工具]
#初始化一个标准python项目
uv init [-p <python版本>]
#自动帮你修改toml文件
uv add <python库>
#把这个库安装到开发环境
uv add --dev python-dotenv
#列出所有的依赖关系
uv tree
#工具将安装到全局
uv tool install <工具名>
uv tool list
#根据当前项目的toml文件自动下载全部依赖
uv sync
#不要开发依赖
uv sync --no-dev
#清除uv的下载库的缓存,有时候下不动了可以用
uv cache clean

常用的库#

库名PIP 安装命令描述
opencvuv add opencv-python开源计算机视觉库,用于图像处理和计算机视觉任务
matplotlibuv add matplotlibPython 绘图库,创建静态、动态和交互式可视化
numpyuv add numpy科学计算基础包,提供多维数组对象和各种派生对象
os(Python 内置)操作系统接口模块,提供文件和目录操作功能
subprocess(Python 内置)用于创建和管理子进程,执行外部命令
pynputuv add pynput控制和监控输入设备的库,支持键盘和鼠标监听
flaskuv add flask轻量级 Web 框架,简单灵活,适合小型项目和 API
djangouv add django高级 Web 框架,功能完整,适合大型企业级应用
fastapiuv add fastapi现代高性能 Web 框架,基于类型提示,自动生成 API 文档
ruffuv add ruff极速的 Python 代码检查器和格式化工具
BeautifulSouppip install beautifulsoup4HTML 和 XML 解析库,用于网页数据抓取
Pandasuv add pandas数据分析库,提供高性能、易用的数据结构和分析工具
PySideuv add PySide6Qt 框架的 Python 绑定,用于创建桌面应用程序
pathlib(Python 内置)面向对象的文件系统路径操作模块
IPythonuv tool install ipython一个功能强大的 交互式 Python 解释器
jupyteruv tool install jupyterlab一个基于浏览器的交互式计算环境,让你能在网页中写代码、运行代码、并立即看到结果。
tkinter(Python 内置)python自带的ui库
pillowuv add pillowPython 图像库
Requestsuv add requests一个优雅且简单的 Python HTTP 库,专为人类设计。
feedparseruv add feedparserrss解析器
gunicornuv add gunicorn基于 Unix 的 Python WSGI HTTP 服务器
SQLite(Python 内置)轻量级数据库
scapyuv add scapy基于 Python 的交互式数据包作程序和库。
SQLAlchemyuv add sqlalchemyPython SQL 实例和对象关系映射器(ORM)
python-dotenvuv add python-dotenv从 工作目录的.env 文件读取键值对,加载到内存中,os.getenv()来取出
pyjwtuv add pyjwt给web项目的jwt的库
Psycopguv add psycopg2-binaryPostgreSQL的python适配器
Flask-Migrateuv add Flask-Migrate处理 Flask 应用的 SQLAlchemy 数据库迁移(数据库的版本管理)
alembicuv add alembicSQLAlchemy项目下面的数据库迁移的
pydanticuv add pydantic类型验证
taskiquv add taskiq异步分布式任务管理器
pymupdfuv add pymupdfPDF处理库
httpxuv add httpx异步的http请求客户端
richuv tool install rich用于向终端编写富文本(带有颜色和样式)
celeryuv add celery分布式任务队列
inspect(Python 内置)用于自省,太变态了,说实话
contextvars(Python 内置)上下文变量

推荐的开源项目#

saleor开源无头电商系统 odoo开源企业级erp系统

异常#

文档:1 | 2

实践#

在底层实现抛出异常,在上层有能力处理什么异常就except这个异常然后进行处理。千万不要在上层直接except Exception全给排除了,这样底层抛出的一切信息全没了。一定要你这里能负责了,你再except,没法负责你就不要try,except,还不如让这个报错继续网上浮现,让再上面处理,实在不行压根就不用处理,让他走到最上层让框架或者解释器直接打印出来,千万不要看到啥就无脑except Exception,要负责的。 python库的那些异常都会抛出异常的,不需要你去再画蛇添足了,但是比如你要对接第三方的http请求,这种就需要你自己根据响应来自己构建一套这个api专用的异常来抛出了。但是具体要怎么组织项目的异常类,就八仙过海各显神通了。

raise#

只能抛出一个异常类实例,当抛出一个异常之后,当前的线程的所有事情全部停下,开始一层一层的匹配except,一旦匹配到了,那么就进入那个except的块里,进行处理异常的逻辑。如果没有匹配到会浮现到最上层,

异常类#

就和定义一个普通的类一样,但是定义异常类的时候必须继承Exception

try except#

就有点像是一个全局的if,在他的范围内,一直盯着有没有raise出来,有raise出来了就看看是什么类型的exception,从而对异常进行判断和处理。

虚拟环境#

创建虚拟环境#

Terminal window
python -m venv <环境名称> #主流使用.venv

他会在你的当前目录下创建一个对应名称的文件夹环境存在的地方

激活虚拟环境#

Terminal window
# Windows
<环境名称>\Scripts\activate
# macOS/Linux
source <环境名称>/bin/activate

退出虚拟环境#

Terminal window
deactivate

命名规范#

反正除了类用大驼峰和java一样,别的变量名,模块名,函数名全部是用蛇形(全小写,词之间用_分隔),常量使用全大写。 python约定,_单下划线开头的是私有变量,但是其实只是ide里看不到了,实际上真想调用还是可以的不是强制的,下划线的一般是魔法变量,比如__str()这个是print会调用的,转字符串的类似于toString()。

Byte#

python初始化二进制字节流,感觉还是c的定义方式我喜欢一点。

a = b'\x41\x7A' # 把16进制数转化成字节流
b = b'Az' #会把这种字符根据ascii码变成字节流
c = bytes([0x41, 0x7A])
bytearray([0x01]) #这种可以动态的调整字节流的长度,可以不断的添加
print(a == b == c) # 输出: True

‘和”#

python里这俩是完全等价的,老是被c搞得都ptsd了。不过工程上我们最好区分一下使用场景这样更好看好看点,

场景推荐引号暗示的意义
内部标识符/Key'id', 'status'“这是程序内部用的变量名,不是给人读的句子。”
用户可见文本"上传成功"“这是要显示在 UI 上给人看的句子。”
SQL / 正则表达式'SELECT * FROM...'“这是另一种语言的代码块。”
Docstring / 长注释""" ... """“这是属于这个函数的说明书。”

闭包#

这个我转载一篇文章写的非常不错。 我这放俩代码段,非常好理解

#这个函数直接返回了f2函数,f2的函数的域在f1里面,所以可以直接访问n,这样你就可以通过f2来访问到n变量了
def f1():
n=999
def f2():
print(n)
return f2
def timer(func): # 这里的 func 就相当于上面代码里的 n
def wrapper(): # 这里的 wrapper 就是上面代码里的 f2
start = time.time()
func() # 就像 print(n),这里我们执行了这个函数
end = time.time()
print(f"执行耗时: {end - start}s")
return wrapper # 返回内层函数
new_func = timer(my_task)#你把随便一个函数当成func扔进这个timer函数里,就会把他重新构建打包并返回回来,这就是装饰器的最简单的原理

当你写下:

@timer
def my_task():
print("我在干活")

其实就相当于把my_task=timer(my_task),把原来的函数重新通过timer打包了。

真正的装饰器:

import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"执行耗时: {end - start}s")
return result
return wrapper
@timer
def my_task():
time.sleep(1)
print("任务完成")

当你在调用my_task()的时候,这个my_task其实早已经被my_task=timer(my_task)了,这个时候的my_task其实是被处理完返回的了。这就不难理解为啥要 def wrapper(*args, **kwargs): 然后再把这个接收到的参数放到func的参数里了。

  • *args (Arguments):是一个元组 (Tuple)。它负责把所有按位置传进来的参数(比如 1, 2, 3)打包在一起。
  • **kwargs (Keyword Arguments):是一个字典 (Dict)。它负责把所有带名字的参数(比如 a=1, b=2)打包在一起。 把所有的参数全打包起来,然后转手发给func。

这里*args**kwargs,之所以python选择这么起名,在正则里一般*是指匹配任意数量的,args意思是匹配任意数量的参数。而**kwargs意思是匹配任意数量的键值对,如果只有一个意思是只要所有的键,可能是这样

python交互式解释器#

也被叫做:(REPL)[https://docs.python.org/zh-cn/3.14/glossary.html#term-REPL]。一般来说,想要调用python解释器,有两种。一种python <模块>,另一种直接python进入python交互式解释器。

ipython#

其实就是高级版的python交互式解释器,可以很快速的调试一个新库和测试模块,更好使的是他内置了一个Global Event Loop,你可以很方便的直接await一个异步函数,不需要用asyncio.run()来点火,方便极了,用了这个就再也不想用原版的了。 使用方法的话,不知道有什么有什么对象就按tab,不知道对象怎么用的话就按?,非常符合直觉,多用用很快就上手了。但是功能远不止于此啊,建议去看看人家的文档

  • F2:批量写入代码块
python基础
https://blog.cannian.space/posts/2025-10-16-python/
作者
Cannian
发布于
2025-10-16
许可协议
CC BY-NC-SA 4.0