如何在Python中标记类方法返回类实例?(Result类实现疑问)
解决返回类型标注问题
在Python类定义内部,类尚未完全初始化时直接使用类名Result作为返回类型注解会引发错误,以下是几种可行的解决方式:
方法1:使用字符串字面量标注
Python 3.7+支持延迟注解,直接用类名字符串代替类本身即可:
from typing import Any class Result: def __init__(self, value: Any, status: bool = True) -> None: self.value = value self.status = status @classmethod def Ok(cls, result: Any) -> "Result": return cls(result, status=True) @classmethod def Err(cls, error: Any) -> "Result": return cls(error, status=False) def unwrap(self): if self.status: print("from Result -> self.status TRUE") print(f"from Result -> self.value = {self.value}") return self.value else: print("from Result -> self.status FALSE") print(f"from Result -> self.value = {self.value}") return self.value
方法2:使用Self类型(Python 3.11+)
Python 3.11引入了typing.Self类型,专门用于标注返回当前类实例的方法:
from typing import Any, Self class Result: def __init__(self, value: Any, status: bool = True) -> None: self.value = value self.status = status @classmethod def Ok(cls, result: Any) -> Self: return cls(result, status=True) @classmethod def Err(cls, error: Any) -> Self: return cls(error, status=False) def unwrap(self): if self.status: print("from Result -> self.status TRUE") print(f"from Result -> self.value = {self.value}") return self.value else: print("from Result -> self.status FALSE") print(f"from Result -> self.value = {self.value}") return self.value
方法3:兼容旧版本Python(使用typing_extensions.Self)
若需兼容Python 3.10及以下版本,先安装typing_extensions库:
pip install typing_extensions
再导入并使用Self:
from typing import Any from typing_extensions import Self class Result: def __init__(self, value: Any, status: bool = True) -> None: self.value = value self.status = status @classmethod def Ok(cls, result: Any) -> Self: return cls(result, status=True) @classmethod def Err(cls, error: Any) -> Self: return cls(error, status=False) def unwrap(self): if self.status: print("from Result -> self.status TRUE") print(f"from Result -> self.value = {self.value}") return self.value else: print("from Result -> self.status FALSE") print(f"from Result -> self.value = {self.value}") return self.value
关于-> __init__的问题
你不能用__init__作为返回类型注解,原因如下:
__init__是类的构造方法,其返回值固定为None,不会返回类实例;- 返回类型注解需要标注方法实际返回的对象类型,此处应标注为
Result实例而非构造方法本身。
正确写法参考上述几种方式,用"Result"或Self标注返回类型即可。
可选优化:泛型Result类(更贴近Rust的类型安全)
当前实现使用Any作为值类型,缺少类型约束。可以通过泛型让Result明确区分Ok值和Err值的类型,更贴近Rust的设计:
from typing import Generic, TypeVar, Self T = TypeVar('T') E = TypeVar('E') class Result(Generic[T, E]): def __init__(self, value: T | E, status: bool = True) -> None: self.value = value self.status = status @classmethod def Ok(cls, result: T) -> Self[T, E]: return cls(result, status=True) @classmethod def Err(cls, error: E) -> Self[T, E]: return cls(error, status=False) def unwrap(self) -> T: if self.status: return self.value # type: ignore else: raise ValueError(f"Cannot unwrap Err value: {self.value}") # 使用示例 def divide(a: int, b: int) -> Result[int, str]: if b == 0: return Result.Err("Division by zero") return Result.Ok(a // b) result = divide(10, 2) print(result.unwrap()) # 输出5 err_result = divide(10, 0) err_result.unwrap() # 抛出ValueError
这个泛型版本不仅能提供类型提示,还能在unwrap Err值时抛出异常,更符合Rust中unwrap的行为逻辑。
内容的提问来源于stack exchange,提问作者userh897
相关产品推荐
相关产品推荐

