You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cython新手求教:如何扩展Python标准库的ContextDecorator类?

在Cython中扩展ContextDecorator的方法

嘿,很高兴你在尝试用Cython重构模块!扩展Python的ContextDecorator在Cython里其实和纯Python思路一致,但要注意Cython的类定义语法,我给你一步步说明,附上可运行的示例:

1. 核心思路:继承并实现上下文管理器方法

ContextDecorator的作用是让一个类同时能作为上下文管理器和装饰器,所以你需要在Cython类中:

  • 继承自contextlib.ContextDecorator
  • 实现__enter__和__exit__这两个上下文管理器必备的方法

2. 完整Cython示例代码

创建一个my_decorator.pyx文件,内容如下:

# 导入Python标准库的ContextDecorator
from contextlib cimport ContextDecorator
from time cimport clock

cdef class TimingDecorator(ContextDecorator):
    """一个计时的上下文装饰器,同时支持with语句和装饰器语法"""
    cdef double start_time

    def __enter__(self):
        # 进入上下文时记录开始时间
        self.start_time = clock()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # 退出上下文时计算并打印耗时
        elapsed = clock() - self.start_time
        print(f"耗时:{elapsed:.4f}秒")
        # 返回False表示如果有异常会继续抛出,返回True会吞掉异常
        return False

3. 编译Cython代码

创建setup.py来编译这个模块:

from setuptools import setup
from Cython.Build import cythonize

setup(
    name="TimingDecorator",
    ext_modules=cythonize("my_decorator.pyx"),
)

然后运行命令编译:

python setup.py build_ext --inplace

4. 测试使用

编译完成后,就可以在Python中使用这个类了:

from my_decorator import TimingDecorator

# 作为上下文管理器使用
with TimingDecorator():
    for i in range(10**6):
        pass

# 作为装饰器使用
@TimingDecorator()
def slow_function():
    for i in range(10**6):
        pass

slow_function()

常见错误排查

  • 忘记继承ContextDecorator:如果你的类没继承这个基类,就无法自动获得装饰器功能,只能当普通上下文管理器用。
  • __exit__方法参数错误:这个方法必须接受exc_type, exc_val, exc_tb三个参数,少一个都会导致运行时错误。
  • Cython类型声明问题:如果在类里用了cdef变量,要确保类型正确,比如示例中的start_time用double类型,对应C的双精度浮点数。

因为你是C语言新手,尽量先从这种简单的继承开始,避免直接写底层C扩展代码,Cython已经帮你封装了大部分和Python交互的细节,先专注于Python层面的逻辑实现就好。

内容的提问来源于stack exchange,提问作者user3758232

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:05:49