Blender插件开发疑问:能否在函数中更新变量的类型注解?
Blender插件开发:变量类型注解更新报错的解决方法
问题背景
开发Blender插件时,编写顶点去重函数,流程是先将重复顶点标记为None,再过滤清除。尝试在函数内更新变量vertices的类型注解(从list[Vertex]改为list[Vertex|None],再改回list[Vertex]),但编辑器报错:Declaration "vertices" is obscured by a declaration of the same name。
代码示例:
def deduplicate(vertices: list[Vertex]): # 报错:Declaration "vertices" is obscured by a declaration of the same name vertices: list[Vertex|None] = vertices.copy() # 去重逻辑:标记重复元素为None ... # 过滤None vertices: list[Vertex] = [v for v in vertices if v != None]
不想用不同变量名(繁琐)或关闭类型检查(失去类型提示优势),询问是否有可行的解决方法。
可行解决方案
方法1:使用类型断言(typing.cast)
通过cast函数告诉类型检查器变量的类型变化,无需重新声明变量类型,避免遮蔽报错。
示例代码:
from typing import cast, Union def deduplicate(vertices: list[Vertex]) -> list[Vertex]: # 复制后,断言列表可包含None vertices = cast(list[Union[Vertex, None]], vertices.copy()) # 去重逻辑:标记重复顶点为None seen = set() for idx, v in enumerate(vertices): if v in seen: vertices[idx] = None else: seen.add(v) # 过滤None后,断言回仅包含Vertex的列表 vertices = cast(list[Vertex], [v for v in vertices if v is not None]) return vertices
cast仅作用于类型检查阶段,不会影响代码运行时逻辑,既保留了类型检查的优势,又不需要更换变量名。
方法2:使用局部临时变量(更清晰的流程划分)
如果觉得cast不够直观,可以用临时变量区分不同阶段的列表类型,这其实也符合Python的可读性原则:
def deduplicate(vertices: list[Vertex]) -> list[Vertex]: # 临时变量存储可能含None的列表 temp_vertices: list[Vertex|None] = vertices.copy() # 去重逻辑:标记重复元素为None seen = set() for idx, v in enumerate(temp_vertices): if v in seen: temp_vertices[idx] = None else: seen.add(v) # 过滤后得到最终顶点列表 filtered_vertices: list[Vertex] = [v for v in temp_vertices if v is not None] return filtered_vertices
这种方式通过变量名明确区分不同阶段的状态,类型检查器不会报错,代码可读性也更强。
结论
变量的类型注解本身不能在函数内重复声明(会触发遮蔽报错),但可以通过typing.cast或临时变量的方式实现类型的“更新”,同时保留类型检查的优势。
内容的提问来源于stack exchange,提问作者ProgramGamer
相关产品推荐
相关产品推荐

