从Cython中暴露一个文件对象

20 投票
1 回答
1247 浏览
提问于 2025-04-16 07:36

我需要从一个C库中暴露一个类似文件的对象,而这个库是我用Cython模块封装的。我想重用Python的通用输入输出代码,比如缓冲、读取一行等功能。

新的IO模块看起来正是我需要的,但从Cython中使用它似乎并不简单,我尝试了几种方法:

  • 我在一个cdef类中,继承自IO.RawIOBase - 这个方法失败了,因为cdef类只能继承其他Cython的cdef类,而IO是“原生”的C。

  • 我在一个cdef类中,另一个(非cdef)类同时继承我的cdef类和RawIOBase - 结果失败,出现“TypeError: multiple bases have instance lay-out conflict”的错误。

  • 我在一个(非cdef)类中,继承自RawIOBase - 这个方法可以,但我失去了在类中存储我需要与底层库通信的C级别内容的能力,所以我需要在它周围做一个cdef的包装,并把它作为一个成员存储……这看起来很麻烦。

  • 我在一个cdef类中,不继承(Raw)IOBase,而是重新实现它的功能,Python代码将我的对象包装在BufferedReader/BufferedWriter中 - 这个方法似乎可行,而且比之前的选项更简单。

我有几个问题:

1) 我是不是漏掉了什么,或者在这里重复造轮子?

2) 我需要实现IOBase中的哪些具体内容,才能让BufferedReader/Writer在当前和未来的Python版本中与我的对象兼容?这些有文档说明吗?

3) 在Python 2.6中,IO是纯Python的,这样会怎样?我想性能可能会受影响,但应该还是能用,对吧?

1 个回答

1

直接用底层库返回的文件描述符号来调用 os.fdopen(),然后再用普通的Python方法去处理这个文件对象进行输入输出,这样做会不会太低效呢?对于大多数输入输出操作,我觉得你可能看不出直接调用C语言的函数和让Python的方法去调用它之间有什么区别。不过,当然了,你可能会遇到一些特殊情况,我也可能是错的!

撰写回答