- 后端
【免费下载链接】gspread
Google Sheets Python API
本篇指南围绕 gspread(Google Sheets Python API)的Cell模型展开,系统讲解单元格对象的构造方式、A1 地址与行列号的转换机制、数值自动解析(numericise)规则,以及它在Worksheet读写、查找与批量更新流程中的核心作用。读完本文,你将掌握Cell的全部属性与类方法,能够独立实现基于单元格的读取、写入、批量更新与内容查找,并理解其底层实现原理。
Cell 模型在 gspread 中的地位
Cell是 gspread 中用于表示单个工作表单元格的数据模型,定义于 gspread/cell.py 的gspread.cell.Cell类。它是Worksheet上几乎所有单格操作的返回值类型:无论是按 A1 地址读取(acell)、按行列号读取(cell)、在表中查找内容(find/findall),还是批量更新(update_cells),最终打交道的对象都是Cell。
官方 API 文档 docs/api/models/cell.rst 通过 Sphinx 的autoclass指令直接抽取该类的 docstring 与成员生成参考文档,因此本文以源码实现为准,逐一还原该模型的完整行为。在 gspread 的公开命名空间中,Cell通过 gspread/init.py 的from .cell import Cell直接导出,因此你可以直接用gspread.Cell(...)或from gspread import Cell进行实例化。
构造一个 Cell:构造函数与 from_address
Cell的构造函数签名如下(gspread/cell.py):
def __init__(self, row: int, col: int, value: Optional[str] = "") -> None: self._row: int = row self._col: int = col #: Value of the cell. self.value: Optional[str] = value参数说明:
row:单元格所在行号,从 1 开始计数(与 Google Sheets UI 一致,而非 0 起始)。col:单元格所在列号,同样从 1 开始计数(1 表示 A 列,2 表示 B 列……)。value:单元格的值,可选,默认为空字符串"",类型为Optional[str]。
直接构造示例:
import gspread # 创建一个位于第 1 行第 2 列(即 B1)、值为 "Foo Bar" 的单元格 cell = gspread.Cell(1, 2, "Foo Bar") print(cell.address) # B1除了直接传入行列号,Cell还提供了类方法from_address,可以从A1 记号(如"A1"、"C3")直接创建实例(gspread/cell.py):
@classmethod def from_address(cls, label: str, value: str = "") -> "Cell": row, col = a1_to_rowcol(label) return cls(row, col, value)它内部调用gspread.utils.a1_to_rowcol完成地址解析,再委托给构造函数,返回的仍是Cell实例:
cell = gspread.Cell.from_address("A1", "Foo Bar") print(cell.address) # A1 print((cell.row, cell.col)) # (1, 1) print(cell.value) # Foo Bar从源码结构看,from_address是"把 A1 地址字符串转成单元格对象"的快捷入口,在实际使用中,读取流程通常由Worksheet完成,直接构造Cell更多用于组装待写入的数据(见下文批量更新)。
核心属性:row、col、address 与 value
Cell对外暴露四个核心成员,其中前三个为只读属性(底层为私有字段_row/_col),value为可读写字段。
row 与 col:行列号(从 1 开始)
gspread/cell.py 定义了两个只读属性:
@property def row(self) -> int: """Row number of the cell.""" return self._row @property def col(self) -> int: """Column number of the cell.""" return self._col注意行号与列号均以 1 为起始,这与Worksheet.cell(row, col)的参数约定完全一致。
address:A1 记号地址
address属性把内部的行列号转换为 A1 记号字符串(gspread/cell.py):
@property def address(self) -> str: """Cell address in A1 notation.""" return rowcol_to_a1(self.row, self.col)其底层实现是 gspread/utils.py 的rowcol_to_a1:
- 若
row < 1或col < 1,抛出IncorrectCellLabel异常; - 列号通过 26 进制循环换算为字母(
A–Z、AA、AB……),再拼接行号,例如rowcol_to_a1(1, 1)返回"A1"。
value:单元格值
value是Cell上唯一的可变字段,保存 Google Sheets 返回的原始值(字符串)。在批量更新场景中,你通常直接给cell.value赋值,再交给update_cells一次性写回(见下文)。
repr输出格式
Cell实现了__repr__(gspread/cell.py),输出形如:
<Cell R1C1 "I'm cell A1">格式为<类名 R行C列 值repr>。这也是Worksheet.acell('A1')等读取方法的典型返回打印结果。
数值解析:numeric_value 属性
numeric_value是Cell最实用的派生属性之一,它尝试把字符串形式的单元格值智能转换为数值(gspread/cell.py):
@property def numeric_value(self) -> Optional[Union[int, float]]: numeric_value = numericise(self.value, default_blank=None) if isinstance(numeric_value, int) or isinstance(numeric_value, float): return numeric_value else: return None它委托给 gspread/utils.py 的numericise函数,转换规则(与numericise的 docstring 示例一致)为:
| 输入值 | numericise结果 | numeric_value结果 |
|---|---|---|
"3" | 3(int) | 3 |
"3.1" | 3.1(float) | 3.1 |
"2,000.1" | 2000.1(自动去除千位分隔逗号) | 2000.1 |
"faa"/ 非数字文本 | 原字符串 | None |
""(空字符串,default_blank=None) | None | None |
"3_2"(默认不允许下划线数字字面量) | "3_2"原样返回 | None |
numericise的实现细节包括:
- 先尝试
int(),失败再尝试float(); - 转换前会移除千位分隔逗号,所以
"2,000,000.01"可正确解析为2000000.01; - 默认不开启
allow_underscores_in_numeric_literals,因此带下划线的字面量(如"3_2")不会被当作数字; - 空字符串的行为由
empty2zero(默认False)与default_blank(默认"")控制;numeric_value传入default_blank=None,保证空值返回None而不是""。
测试 tests/cell_test.py 的test_numeric_value验证了这些行为:对公式= 1 / 1024的单元格可得到1.0 / 1024的 float 结果,对"2,000,000.01"可得到2000000.01,而对"Non-numeric value"返回None。
相等性比较:eq的语义
Cell重写了__eq__(gspread/cell.py),两个单元格相等当且仅当行、列、值三者全部相同:
def __eq__(self, other: object) -> bool: if not isinstance(other, Cell): return False same_row = self.row == other.row same_col = self.col == other.col same_value = self.value == other.value return same_row and same_col and same_value这与测试 tests/cell_test.py 的test_equality完全对应:同一单元格经acell("A1")与cell(1, 1)两种方式读取后相等;行不同(A2)或列不同(B1)的单元格即使值相同也不相等。注意:由于__eq__存在而__hash__未定义,Cell实例会被视为不可哈希对象,不应作为字典键或集合元素使用。
与 Worksheet 的联动:读取、写入、查找与批量更新
Cell模型的价值体现在它与Worksheet各类方法的配合中。以下方法均以Cell为核心数据载体(实现见 gspread/worksheet.py)。
按地址读取:acell
gspread/worksheet.py 的acell(label, value_render_option=ValueRenderOption.formatted)接收 A1 记号字符串,内部调用a1_to_rowcol转为行列号后交给cell(),返回Cell实例:
cell = worksheet.acell("A1") # 读取 A1 print(cell.row, cell.col, cell.value, cell.address)按行列号读取:cell
gspread/worksheet.py 的cell(row, col)是底层读取入口,两个参数均从 1 开始,返回Cell:
cell = worksheet.cell(1, 1) # 等价于 worksheet.acell("A1")两者的返回值打印效果均为<Cell R1C1 "I'm cell A1">这类__repr__输出。
单格写入:update_acell 与 update_cell
写入侧同样存在 A1 / 行列号两套入口:
- gspread/worksheet.py 的
update_acell(label, value):内部用a1_to_rowcol解析地址后调用update_cell; - gspread/worksheet.py 的
update_cell(row, col, value):用rowcol_to_a1拼出 A1 地址,再经absolute_range_name构造完整范围名(工作表名!A1),调用底层client.values_update,默认使用ValueInputOption.user_entered(即值会被当作"用户输入"解析,数字保持为数字,字符串可能被转换为日期/数字等)。
worksheet.update_acell("A1", "42") worksheet.update_cell(1, 2, 3.14)批量更新:update_cells
update_cells(cell_list, value_input_option=ValueInputOption.raw)(gspread/worksheet.py)接收一组Cell对象,是Cell最典型的批量用法:
cell_list = worksheet.range("A1:C7") for cell in cell_list: cell.value = "O_o" worksheet.update_cells(cell_list)其核心是 gspread/utils.py 的cell_list_to_rect:它把散布的Cell列表按行列坐标聚合成"矩形"二维列表,计算row_offset/col_offset做坐标归一化;缺失的单元格在矩阵中留None占位,意味着该格不更新。默认的ValueInputOption.raw表示值原样存储、不做任何解析;如需像用户在 UI 中输入那样解析,可传ValueInputOption.user_entered。
内容查找:find 与 findall
查找方法的返回类型同样是Cell:
- gspread/worksheet.py 的
find(query, in_row=None, in_column=None, case_sensitive=True):返回第一个匹配的Cell,找不到时返回None;query可以是普通字符串或编译后的正则表达式; - gspread/worksheet.py 的
findall(...):返回所有匹配的Cell列表,无匹配时返回空列表。
result = worksheet.find("Dummy") # 返回 Cell 或 None if result is not None: print(result.address, result.value) # B1 Dummy测试 tests/cell_test.py 的test_a1_value完整串联了这些行为:cell(4, 4).address == "D4";find("Dummy")返回的单元格address == "B1"且value == "Dummy";同时验证了gspread.Cell(1, 2, "Foo Bar").address == "B1"与from_address("A1", ...)的构造结果。
底层坐标转换与异常处理
Cell相关的坐标转换集中在 gspread/utils.py,两个函数互为逆运算:
a1_to_rowcol(label)(gspread/utils.py):解析 A1 地址,忽略字母大小写,按 26 进制还原列号,返回(row, col);地址格式不合法时抛出IncorrectCellLabel。rowcol_to_a1(row, col)(gspread/utils.py):行列号转 A1 字符串;row < 1或col < 1时抛出IncorrectCellLabel。
IncorrectCellLabel定义在 gspread/exceptions.py,并随gspread顶层命名空间导出(见 gspread/init.py)。在 gspread 的坐标体系中,所有行列下标统一从 1 开始,而 Google Sheets API 底层使用 0 起始索引,这一差异由 gspread 内部转换屏蔽,对使用者透明。
常见用法速查
以下代码汇总了Cell模型的典型使用路径:
import gspread gc = gspread.service_account("credentials.json") sh = gc.open("My Spreadsheet") ws = sh.sheet1 # 1. 读取:按 A1 地址 / 按行列号 c1 = ws.acell("A1") # <Cell R1C1 "..."> c2 = ws.cell(1, 2) # B1 # 2. 读取数值(自动去除千位逗号、转 int/float) print(c1.numeric_value) # 数字或 None # 3. 写入单个单元格 ws.update_acell("A1", "42") ws.update_cell(1, 2, 3.14) # 4. 查找并定位 hit = ws.find("关键字", case_sensitive=False) if hit: print(hit.address, hit.value) # 5. 批量更新:改值后一次性写回 cells = ws.range("A1:C7") for cell in cells: cell.value = "O_o" ws.update_cells(cells) # 默认 raw,原样存储 # 6. 手动构造 Cell(例如组装写入数据) new_cell = gspread.Cell.from_address("D4", "合计")总结
Cell是 gspread 中连接"地址表示"与"数据读写"的枢纽模型:它把(row, col)行列号、A1 记号地址和单元格值封装为单一对象,并通过numeric_value提供贴近实际使用的数值解析能力;而from_address、__eq__与update_cells/cell_list_to_rect的组合,则让"构造单元格 → 批量改值 → 一次写回"成为最高效的写入范式。理解Cell及其在 gspread/utils.py、gspread/worksheet.py 中的协作方式,是掌握 gspread 工作表编程的必修课。
- 后端
【免费下载链接】gspread
Google Sheets Python API
相关推荐
TanStack Svelte Table 单元格合并(Cell Spanning)完整指南:行合并、列合并与源码解析
TanStack Svelte Table 单元格合并(Cell Spanning)完整指南:行合并、列合并与源码解析 导读 本文围绕 TanStack Tab
前端UI组件TanStack Vue Table 单元格合并(Cell Spanning)完整指南:spanRows 行合并与 spanColumns 列合并的配置、渲染与源码剖析
TanStack Vue Table 单元格合并(Cell Spanning)完整指南:spanRows 行合并与 spanColumns 列合并的配置、渲染与
前端UI组件TanStack Solid Table 单元格合并(Cell Spanning)实战指南:跨行/跨列合并、汇总行与源码机制剖析
TanStack Solid Table 单元格合并(Cell Spanning)实战指南:跨行/跨列合并、汇总行与源码机制剖析 本指南以 Solid 版 Ce
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考