《从 Gopher 到 Pythonista,Python 快速上手指南》- 学习笔记1

目录

对的,这是一篇学习笔记,和上一篇没啥关系。

此刻,我写不来 Python,我也记不得多少关于 Python 的知识点。上次写 Python 代码是2017年,上次有学 Python 的想法是 2023 年,不过只学了半天。

今天,准备从0到1,快速入个门。

一个 Python 项目的典型结构入下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
project_name/                        # 项目根目录
├── project_name/                    # 源码包 (Package) - 核心代码存放地
│   ├── __init__.py                  # 标识此目录为Python包,可包含包初始化代码或定义__all__列表
│   ├── module1.py                   # 模块1:包含相关函数、类等
│   ├── module2.py
│   └── subpackage1/                 # 子包1,用于更深层次的模块化组织
│       ├── __init__.py
│       ├── module3.py
│       └── module4.py
├── tests/                           # 测试目录 - 存放所有单元测试和集成测试
│   ├── __init__.py
│   ├── test_module1.py              # 针对module1的测试
│   ├── test_module2.py
│   └── test_subpackage1/            # 针对子包的测试也可以有相应目录
│       ├── __init__.py
│       └── test_module3.py
├── docs/                            # 项目文档目录 - 使用Sphinx等工具生成详细文档
│   ├── conf.py
│   ├── index.rst
│   └── ...
├── scripts/                         # 脚本目录 - 存放可执行脚本、工具脚本
│   ├── data_cleaning.py
│   ├── train_model.py
│   └── start_server.py
├── data/                           # (可选)数据目录 - 存放项目所需或生成的数据
│   ├── input/
│   └── output/
├── examples/                       # (可选)示例目录 - 存放使用项目的示例代码
├── requirements.txt                # 项目依赖清单 - 列明项目运行所需的所有第三方库及其版本
├── requirements_dev.txt            # (可选)开发环境额外依赖(如测试、构建、文档工具)
├── setup.py                        # 打包和安装脚本 - 用于将项目打包分发给其他人安装使用
├── pyproject.toml                  # 现代项目构建配置文件 (遵循PEP 518)
├── README.md                       # 项目说明文档 - 简介、安装、快速使用等
├── LICENSE                         # 项目许可证文件 - 明确授权条款
└── .gitignore                      # Git忽略规则 - 指定哪些文件/目录不应纳入版本控制

一个 py 文件就是一个模块,模块代码的整体布局如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"""
This module provides some example classes and functions to demonstrate Python code layout and style.
"""

__version__ = '0.1.0'
__author__ = 'Jane Developer'
__all__ = ['MyClass', 'my_function', 'CONSTANT1']

# Standard Library Imports
import os
import sys

# Third-Party Imports
import requests

# Local Application/Library Specific Imports
from myutils.helpers import format_data

# Global constants
CONSTANT1 = 10
DEFAULT_TIMEOUT = 30

class MyClass:
    """
    A brief description of MyClass.

    More detailed description of the class's purpose and functionality.
    """

    CLASS_CONSTANT = 'some_value'

    def __init__(self, name):
        self.name = name

    def method_one(self):
        """Does a specific thing."""
        pass

    def method_two(self):
        """Does another thing."""
        pass

def my_function(param1, param2=None):
    """
    A brief description of what this function does.

    Args:
        param1 (str): Description of the first parameter.
        param2 (int, optional): Description of the second parameter. Defaults to None.

    Returns:
        bool: Description of the return value.

    Raises:
        ValueError: Under what conditions it's raised.
    """
    if not param1:
        raise ValueError("param1 cannot be empty.")
    
    result = do_something_complex(param1, param2)
    return result

def _private_helper_function():
    """A non-public function (indicated by the leading underscore)."""
    pass

# Main execution block
if __name__ == "__main__":
    # Code here runs only when the module is executed directly,
    # not when it is imported.
    instance = MyClass("test")
    result = my_function("hello")
    print(result)

代码可以通过包和模块组织,那么跨包或者跨模块调用代码是,就需要 import。Python 里的 import 可以导入包、导入模块、可以导入任何定义在模块顶级的名称,包括变量、常量、函数、类等。

假如有这样一个项目:

1
2
3
4
5
6
my_project/
├── main.py           # 主程序,用于演示导入
└── my_package/       # 自定义的包
    ├── __init__.py   # 包的初始化文件
    ├── module_a.py   # 包内的一个模块
    └── module_b.py   # 包内的另一个模块

各个文件内容如下:

  1. my_package/__init__.py​
1
2
3
4
5
6
7
8
print("执行 my_package 的 __init__.py 文件")
# 定义一些包级别的变量或执行初始化代码
PACKAGE_NAME = "my_package"
VERSION = "1.0"

# 可以选择将包内模块的特定内容“提升”到包级别,方便用户直接访问
# from .module_a import hello_from_a  # (先注释掉,待会演示)
# from .module_b import hello_from_b  # (先注释掉,待会演示)
  1. my_package/module_a.py​
1
2
3
4
print("执行 module_a.py 模块")

def hello_from_a():
    return "Hello from Module A!"
  1. my_package/module_b.py
1
2
3
4
print("执行 module_b.py 模块")

def hello_from_b():
    return "Hello from Module B!"
  1. main.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
print("--- 开始执行 main.py ---")

print("\n1. 导入整个包 my_package")
import my_package  # 这会执行 my_package/__init__.py

print("\n2. 从包中导入特定模块 module_a")
from my_package import module_a  # 由于包已被导入,__init__.py 不会再次执行,但会执行 module_a.py

print("\n3. 从模块中导入特定函数")
from my_package.module_b import hello_from_b  # 导入包内模块的具体函数
print(hello_from_b())  # 调用函数

print("\n--- main.py 执行结束 ---")

最后的执行结果是这样的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
--- 开始执行 main.py ---

1. 导入整个包 my_package
执行 my_package 的 __init__.py 文件

2. 从包中导入特定模块 module_a
执行 module_a.py 模块

3. 从模块中导入特定函数
执行 module_b.py 模块
Hello from Module B!

--- main.py 执行结束 ---

当你用 pip install 安装一个 Python 包的时候,这个三方包会安装在同一个目录里(藏着你电脑里的某个 site-packages 目录下),比如 /opt/homebrew/lib/python3.11/site-packages,那么当你本地有多个项目依赖同一个包时,这个包的版本就被迫要保持一致了。于是乎,“依赖冲突”问题、“环境隔离与污染”问题接踵而至。甚至你要运行的多个项目依赖的 Python 版本也不尽相同。

所以你需要给每个项目准备单独的 Python 环境。

Python 标准库自带的轻量级组合,简单直接。

  • ​管理工具: pip(包安装) + venv(环境隔离)
  • ​虚拟环境: 需手动创建和管理 (python -m venv .venv)
  • ​依赖记录: 使用 requirements.txt文件,通过 pip freeze > requirements.txt生成,通过 pip install -r requirements.txt安装。​它仅记录包列表,无法保证深层依赖的版本绝对一致。
  • ​优点: Python 自带,无需额外安装;简单灵活。
  • ​缺点: 功能相对基础,依赖解析和冲突解决能力较弱;需要手动管理环境和依赖文件。
  • ​适用场景: 快速尝试、运行简单脚本或初学者学习

强大的开源包管理和环境管理系统,尤其擅长处理数据科学领域的复杂依赖。

  • ​管理工具: conda(或更快的 mamba)
  • ​虚拟环境: ​内置,自动管理 (conda create -n myenv python=3.10)
  • ​依赖记录: 使用 environment.yml文件,通过 conda env export > environment.yml导出环境。
  • ​核心优势: 能够管理非Python依赖​(如C/C++库、R语言、CUDA工具链),预构建的二进制包丰富,解决复杂科学计算依赖的能力非常突出。
  • ​缺点: 包体积通常较大;生态更侧重于数据科学领域。
  • ​适用场景: ​数据科学、机器学习、生物信息学等需要复杂计算栈或跨语言环境的项目

现代化的全能工具,集依赖管理、虚拟环境、打包发布于一身的项目生命周期管理工具。

  • ​管理工具: poetry
  • ​虚拟环境: ​内置,自动创建和管理(也可指定现有环境)。
  • ​依赖记录: 使用 ​pyproject.toml​ (PEP 621标准) 声明依赖和项目元数据,并生成 ​poetry.lock​ 文件精确锁定所有次级依赖的版本,确保环境绝对可复现。
  • ​核心优势: ​依赖解析能力强;统一配置​(一切都在 pyproject.toml中);原生支持打包和发布到PyPI;严格的项目结构建议。
  • ​缺点: 需要单独安装;对某些极特殊的非PyPI依赖处理稍显复杂。
  • ​适用场景: ​纯Python的应用程序、库开发,尤其适合团队协作和追求项目规范与可复现性的场景。

实例:创建一个简单的 Web 爬虫项目

  1. 创建虚拟环境
1
2
3
4
5
mkdir py-projects
cd py-projects
mkdir my-web-crawler
cd my-web-crawler
python -m venv .venv

此时你的 my-web-crawler 目录内会包含如下内容:

1
2
3
4
5
.venv
├── bin
├── include
├── lib
└── pyvenv.cf

激活虚拟环境后,pythonpip 命令就会使用 .venv 里的:

1
source .venv/bin/activate

然后 python3 命令就指向了当前项目的 venv 里的 python3

1
2
3
4
5
6
# ls .venv/bin
Activate.ps1  activate.csh  pip           pip3.11       python3
activate      activate.fish pip3          python        python3.11

# which python3
/Users/danielhu/Work/py-projects/my-web-crawler/.venv/bin/python3
  1. 安装依赖,编写代码

接着安装 requests 包:

1
pip install requests

此时 requests 会被安装到 .venv/lib/python3.11/site-packages/requests 路径。

新建一个 main.py 文件,写入代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import requests
from bs4 import BeautifulSoup

url = 'https://www.danielhu.cn/'

try:
    response = requests.get(url)
    response.raise_for_status() # 检查请求是否成功

    # 使用 BeautifulSoup 解析 HTML 并获取页面标题
    soup = BeautifulSoup(response.text, 'html.parser')
    page_title = soup.title.string if soup.title else 'No title found'
    print(f"The title of '{url}' is: {page_title}")

except requests.RequestException as e:
    print(f"An error occurred while fetching the URL: {e}")

安装 beautifulsoup4

1
pip install beautifulsoup4
  1. 执行代码
1
2
# python main.py
The title of 'https://www.danielhu.cn/' is: 胡涛的个人网站 | Seven Coffee Cups

生成依赖清单:

1
pip freeze > requirements.txt

此时 requirements.txt 内容如下:

1
2
3
4
5
6
7
8
beautifulsoup4==4.13.5
certifi==2025.8.3
charset-normalizer==3.4.3
idna==3.10
requests==2.32.5
soupsieve==2.8
typing_extensions==4.15.0
urllib3==2.5.0

这些包都在 .venv/lib/python3.11/site-packages/requests 里面。

  1. 退出虚拟环境

需要退出虚拟环境,可以直接执行 deactivate

  1. 复现环境

现在将依赖已经全部维护到了 requirements.txt 文件里,这个 requirements.txt 会跟着源代码一起上库,但是 .venv 目录显然是不适合丢到代码库的。

当你下载源代码到一个新环境的时候,就可以通过 requirements.txt 里记录依赖清单来安装依赖,将项目跑起来:

1
pip install -r requirements.txt