Cython扩展类型中的Python字符串

2 投票
1 回答
1252 浏览
提问于 2025-04-16 22:30

我有一个扩展类型(cdef class),里面有一个字符串字段。我不太确定怎么声明它才是最好的。假设有以下代码:

cdef class Box:
    cdef char *_s
    cdef public str s1
    cdef public bytes s2

    property s:
        def __get__(self):
            cdef bytes py_string = self._s
            return py_string

    def __init__(self, s):
        cdef char *aux = s
        self._s = aux
        self.s1 = s
        self.s2 = s

然后使用这个扩展类型:

>>> import test as t
>>> b = t.Box("hello")
>>> b.s
'hello!'
>>> b.s1
'hello'
>>> b.s2
'hello'
>>> type(b.s)
<type 'str'>
>>> type(b.s1)
<type 'str'>
>>> type(b.s2)
<type 'str'>

这些方法都能用,但我不太确定像垃圾回收和字符串对象的生命周期这样的问题。我不喜欢char *加属性的方法,因为这是三种方法中效率最低的。

所以我想问:最好的做法是什么?使用cdef public str s安全吗?

编辑:

好吧,cdef public str s似乎只要在某个地方保持对Box的引用就能正常工作。

>>> gc.collect()
0
>>> gc.is_tracked(b)
True
>>> gc.get_referrers(b.s1)
[<test.Box object at 0x1a4f680>]
>>> gc.get_referrers(b.s2)
[<test.Box object at 0x1a4f680>]
>>> b.s1
'hello'

谢谢。

1 个回答

0

我不太明白你为什么会担心字符串的垃圾回收问题。

如果这个字符串是从另一个C语言程序来的,那就直接复制它的值,这样Box对象就可以拥有这个字符串了。

撰写回答