Skip to main content

Python Rusty Result Library: 在Python中使用Rust风格的Result类型

Project description

pyrsult: Rust 风格的 Result 类型在 Python 中的实现

Python Version License

PyRsult 是 Rust 风格的 Result 类型在 Python 中的实现。
注意: 是 PyRsult 而不是 PyResult 哦,Rs 是 Rust 的意思

pyrsult 是一个超轻量级的 Python 库,提供了类似于 Rust 语言中的Result<T, E>类型。它允许你以更优雅的方式处理可能失败的操作,避免使用异常来控制程序流程,使代码更加健壮和可读。

特性

  • 🦀 Rust 风格的 Result 类型实现
  • 🛡️ 类型安全的错误处理
  • 🧩 简洁的 API 设计
  • 📦 零依赖,纯 Python 实现
  • 🧩 支持泛型类型提示

安装

pip install pyrsult

或者直接将result.py文件复制到你的项目中。

快速开始

from pyrsult import Result
def divide(a: float, b: float) -> Result[float, str]:
    return Result.Success(a / b) if b != 0 else Result.Failure("Division by zero")
# 成功情况
result = divide(10, 2)
print(result)           # Ok(5.0)
print(result.unwrap())  # 5.0
# 失败情况
result = divide(10, 0)
print(result)               # Err('Division by zero')
print(result.unwrap_or(-1))  # -1

核心概念

pyrsult 提供了两种结果类型:

  • Success(T): 表示操作成功,包含一个成功值
  • Failure(E): 表示操作失败,包含一个错误值

API 文档

工厂方法

方法 描述
Result.Success(value) 创建一个成功结果
Result.Failure(error) 创建一个失败结果

判别方法

方法 返回类型 描述
is_ok() bool 是否为成功结果
is_err() bool 是否为失败结果

取值方法

方法 返回类型 描述
unwrap() T 获取成功值,失败时抛出异常
unwrap_err() E 获取错误值,成功时抛出异常
unwrap_or(default) T 获取成功值或默认值
unwrap_or_else(func) T 获取成功值或调用函数处理错误
expect(msg) T 类似 unwrap,但可自定义错误消息

示例用法

# 创建结果
success = Result.Success(42)
failure = Result.Failure("Error occurred")
# 检查结果类型
print(success.is_ok())   # True
print(failure.is_err())  # True
# 安全取值
print(success.unwrap())          # 42
print(failure.unwrap_or(0))      # 0
print(failure.unwrap_or_else(lambda e: len(e)))  # 14
# 带错误消息的取值
try:
    failure.expect("Operation failed")
except ValueError as e:
    print(e)  # Operation failed

实际应用示例

文件操作

def read_file(path: str) -> Result[str, str]:
    try:
        with open(path, 'r') as f:
            return Result.Success(f.read())
    except IOError as e:
        return Result.Failure(str(e))
result = read_file("data.txt")
if result.is_ok():
    print("File content:", result.unwrap())
else:
    print("Error:", result.unwrap_err())

数据验证

def validate_age(age: int) -> Result[int, str]:
    if age < 0:
        return Result.Failure("Age cannot be negative")
    if age > 120:
        return Result.Failure("Age seems unrealistic")
    return Result.Success(age)
user_age = validate_age(25)
match user_age:
    case Result.Success(value):
        print(f"Valid age: {value}")
    case Result.Failure(error):
        print(f"Invalid age: {error}")

链式操作

def process_data(data: str) -> Result[int, str]:
    # 模拟可能失败的操作链
    cleaned = Result.Success(data.strip())
    if not cleaned.unwrap():
        return Result.Failure("Empty data")

    try:
        number = int(cleaned.unwrap())
        return Result.Success(number * 2)
    except ValueError:
        return Result.Failure("Not a number")
result = process_data("  42  ")
print(result.unwrap_or(0))  # 84

设计理念

pyrsult 的设计遵循以下原则:

  1. 显式错误处理:强制开发者显式处理错误情况
  2. 类型安全:通过泛型提供编译时类型检查
  3. 不可变性:Result 对象一旦创建不可修改
  4. 最小化 API:只提供核心方法,保持简洁
  5. Pythonic 风格:遵循 Python 的命名和设计惯例

最佳实践

  1. 避免直接使用unwrap():除非你确定结果一定是成功的
  2. 优先使用unwrap_orunwrap_or_else:提供默认值或错误处理逻辑
  3. 使用expect提供有意义的错误信息:在调试和关键操作中
  4. 保持错误类型简单:通常使用字符串或简单对象作为错误类型
  5. 在 API 边界使用 Result:特别是在模块和包的公共接口

常见问题

Q: 是否支持链式操作? A: 当前版本不直接支持 map/and_then,但可以通过组合实现:

def map_result(result: Result[T, E], func) -> Result[Any, E]:
    return Result.Success(func(result.unwrap())) if result.is_ok() else result

贡献指南

欢迎贡献代码!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

许可证

本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。

更新日志

v0.1.1 (2023-10-18)

  • 完整的 API 文档

v0.1.0 (2023-10-18)

  • 初始版本发布
  • 实现核心 Result 类型
  • 添加 Success 和 Failure 类

pyrsult - 让 Python 的错误处理更加优雅和可靠!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyrsult-0.1.7.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyrsult-0.1.7-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file pyrsult-0.1.7.tar.gz.

File metadata

  • Download URL: pyrsult-0.1.7.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyrsult-0.1.7.tar.gz
Algorithm Hash digest
SHA256 bded7dece8d0c3f2af25897f222766e3496285f2745f9e7c574a50b0cfa0f6fc
MD5 a6924c5c53cc0e6c83442ae2c77f760a
BLAKE2b-256 d6a2e118f883cc90bbe4374af0f7c65d2c52519211e3207064511ec729ccffd8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrsult-0.1.7.tar.gz:

Publisher: python-publish.yml on fexcode/pyrsult

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyrsult-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: pyrsult-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 7.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyrsult-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 9386d9b5770c511d00a570450622c33fd01835a7943824725e34517554fd10c8
MD5 dc8a597b7d5e028c36b9c50ea8e8ecaa
BLAKE2b-256 6608c399da35c5d8694fdb696fb8aeaeed438405d22ed7007036bc08210ced4c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrsult-0.1.7-py3-none-any.whl:

Publisher: python-publish.yml on fexcode/pyrsult

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page