📕 第2章 Python 的准备与基本语法
📄 一句话概括

Mac 上的规矩和 Windows 不一样: 系统里那个 python 是老版本,别动它;自己装的那份要敲 python3。 三条装法各有用途:官方 pkg 最省事,Homebrew 最好维护,pyenv 能同时放好几个版本。 底下都指向同一件事——把解释器装到 PATH 上,再用 venv 隔离包。 这一节在 Windows 上没法执行 Mac 的步骤,所以如实说明,改做两件能真跑的事: 把两个平台的差异列成表,再做一次纯路径解析实验。

📝 本节和前面几节的关系

上一节是 Windows,这一节是 Mac,两节对照着看最省事。 如果你只有 Windows 一台机器,这一节可以只记两件事:路径用 os.path.join 拼、 换行别硬编 \n 以外的假设。其余当背景知识。 2.4 节的「环境写成清单再复现」对两个平台都适用,比本节重要。

一、Mac 上的两个 python

macOS 长期自带一个 Python 2.7,命令叫 /usr/bin/python。 苹果用它跑系统脚本,你不能删也不能改,动了可能影响系统工具。 你自己装的 Python 3 叫 python3, 装在 /usr/local/bin(官方 pkg 或 brew)或 ~/.pyenv/shims(pyenv)。 两套并存,所以Mac 上敲 python 和 python3 是两份不同的东西。 这也是为什么大量教程第一句写着「用 python3, 别用 python」——写 python 有可能踩到那份系统自带的 2.7,报的错全是语法错。

二、Homebrew 与 pyenv 的分工

Homebrew 是 macOS 上的包管理器,brew install python 装最新稳定版,brew upgrade 一键升级。 它管的是「机器上装了什么软件」。 pyenv 管的是「当前目录用哪个版本的 Python」。 pyenv install 3.13.0 装一个版本,pyenv global 3.13.0 设默认, pyenv local 3.11.0 只对当前目录生效。 两个可以一起用:用 brew 装 pyenv,再用 pyenv 装各种 Python 版本。 别用 brew 同时装 python 和 pyenv 的 python,那样 PATH 里谁在前谁生效,很容易搞混。

三、装 Python 3 的三条路

官方 pkg:下载 macOS 64-bit universal2 installer,双击到底。 装完 python3 --version 能答就行。适合只想要一个版本的人。 Homebrew:先装 brew,再 brew install python。好处是升级、卸载、查依赖都统一在 brew 里。 pyenv:适合要同时维护几个项目、各自锁不同版本的人。 代价是多一层 shim,出问题时要 pyenv which python3 确认到底指向谁。

四、虚拟环境与激活

Mac 上建环境是 python3 -m venv v,激活是 source v/bin/activate,退出是 deactivate。 注意是 bin 不是 Scripts,这是两个平台最容易记混的一处。 激活之后命令提示符前面会多出 (v),这时候 which python 应该指向 v/bin/python。 不指就说明激活没生效——常见原因是敲错了路径,或者当前 shell 不是 bash/zsh。 用完 deactivate 退出,环境还在;要彻底清掉就 rm -rf v。 venv 全部内容都在那个目录里,删目录等于删环境。

五、路径与换行:跨平台的坑

Windows 用反斜杠和 CRLF,Mac 用斜杠和 LF。这些差异在写文件、拼路径、读配置时会咬人。 拼路径别自己加斜杠,用 os.path.join("data", "a.csv") 或 pathlib.Path, 它们会按当前平台给对分隔符。 写文本文件时明确 encoding 和 newline:open(p, "w", encoding="utf-8", newline="\n")。 不加 newline,Windows 会把每个 \n 变成 \r\n,文件在 Linux 上读出来多一堆空字符。 下面 Demo 里那个纯路径实验值得亲手跑一遍:同一个字符串, Windows 规则和 POSIX 规则读出来的结构不一样。

六、动手 Demo:在 Windows 上核对两个平台的差异

先说清楚:这一节的 Mac 步骤本机做不了,Homebrew 和 pyenv 都要在 macOS 里跑。 所以 Demo 做两件能真做的事——把两个平台的差异列成表, 再用纯路径对象(不碰磁盘)演示同一串路径在两套规则下的解析结果。

import os, sys
from pathlib import PurePosixPath, PureWindowsPath

print(sys.platform)        # win32
print(repr(os.sep))       # '\\'
print(repr(os.linesep))   # '\r\n'

p = "C:/work/data/part1.csv"
pw, pp = PureWindowsPath(p), PurePosixPath(p)
print(pw.drive, pw.parts)
# ('C:',) ('C:\\', 'work', 'data', 'part1.csv')
print(pp.drive, pp.parts)
# '' ('C:', 'work', 'data', 'part1.csv')

实跑输出:

--------------------------------------------------------------------
Python 的安装~Mac 篇~:在 Windows 上只能核对差异
--------------------------------------------------------------------

  这一节的步骤本机做不了——Mac 上的 Homebrew、pyenv 都要在 macOS 里跑。
  但「同一件事两个平台分别怎么做」是可以当场列表的,而且这张表能背下来。

  事项          Windows                           macOS
  --------------------------------------------------------------------------------
  敲什么启动    python                            python3
  官方安装包    exe 安装包,勾 Add to PATH        pkg 安装包
  包管理器      pip(或 Anaconda)                Homebrew,再用 brew 装 Python
  多版本管理    py 启动器                         pyenv
  虚拟环境目录  venv\Scripts                      venv/bin
  激活命令      activate.bat                      source bin/activate
  路径分隔符    \                                 /
  换行符        CR LF 两个字节                    LF 一个字节

  上面是「人要做的事」,下面是「机器眼里的数」——这一段在 Windows 上也能真跑:

  sys.platform = win32
  os.sep       = '\\'
  os.linesep   = '\r\n'
  PATH 里的 python3 = 找到

  最后一行值得说两句。这台机器上 python3 是能找到的——因为环境里两个名字都建了;
  但**python.org 的 Windows 安装包默认只建 python,不建 python3**,
  而 macOS 上恰恰相反,python 可能是系统自带的旧版,必须敲 python3。
  所以跨平台脚本别硬编解释器名字,写 sys.executable 最稳。

  再做一个纯路径实验(不碰磁盘,只做字符串解析),同一串 C:/work/data/part1.csv:

  用哪种规则解析  盘符      上层目录        文件名      分段数
  -------------------------------------------------------------
  Windows 规则    C:        C:\work\data    part1.csv   4
  POSIX 规则      (空)    C:/work/data    part1.csv   4

  **同一个字符串,两套规则读出两种结构。**
  Windows 认得出 C: 是盘符,POSIX 把 C: 当成一个普通目录名;
  所以跨平台代码里拼路径要用 os.path.join 或 pathlib,别自己拼斜杠。

sys.platform 是 win32、os.sep 是反斜杠、os.linesep 是 CRLF 两字节—— 这三个值就是「当前平台」的全部机器可读信息。跨平台代码判断分支,就看第一个。 路径实验那一块:同一个 C:/work/data/part1.csv,Windows 规则读出盘符 C:、 上层目录 C:\work\data;POSIX 规则读出的盘符是空的,把 C: 当成一个普通目录名。 分段数都是 4,但第一段的含义完全不同。 这就是为什么「在 Mac 上跑 Windows 上写的脚本」经常在路径上炸——字符串看着一样,解析结果不一样。 还有一个小坑:Windows 上 PATH 里的 python3 这一行是「找到」,因为这台机器的环境两个名字都建了; 但 python.org 的 Windows 安装包默认只建 python。 所以写脚本别硬编解释器名字,用 sys.executable 最稳。

30 秒实验

  1. 把路径换成 C:\\Users\\me\\a.txt(反斜杠),再用 PurePosixPath 解析,看 parts 变成什么。
  2. 敲 python -c "import os; print(os.linesep.encode())",看它到底输出几个字节。
  3. 如果你的机器上有 WSL,在 WSL 里跑同一段脚本,对比 sys.platform 和 os.sep 的变化。

常见误区

  1. 在 Mac 上敲 python 而不是 python3。 很可能踩到系统自带的旧版本,报的错是语法错, 看起来像代码写坏了,其实是解释器选错了。
  2. sudo pip install。 一加了 sudo,包就装进系统目录, 之后升级系统或换 Python 版本会留下一堆管不了的残留。永远装在 venv 里。
  3. brew 和 pyenv 各装一份 Python 还都进 PATH。 谁在前面谁生效,今天能跑明天不能跑, 多数是这个原因。
自测三问(点开对答案) 1. Mac 上为什么不能删掉 /usr/bin/python? —— 因为系统的一部分工具脚本依赖它。删了或替换了,可能影响系统功能,而且系统更新会把它装回来。 正确做法是不去动它,另装 python3。 2. Homebrew 和 pyenv 分别管什么? —— brew 管「机器上装了哪些软件」,pyenv 管「当前目录用哪个 Python 版本」。一个管装,一个管选。 3. 为什么拼路径不该自己写斜杠? —— 因为两个平台的分隔符不同,而且反斜杠在字符串里还要转义。 os.path.join 和 pathlib 会按当前平台给对,也顺手处理了多余分隔符。

两个平台的解释器都装好了,接着装包。 下一节回到 Windows,把「装了没有、版本够不够、为什么装不上」这三件事一次说清。

相关笔记