我使用以下密码:
cimport numpy as np
np.import_array()
cdef class Seen:
cdef bint sint_
def __cinit__(self):
print('INIT seen object')
self.sint_ = 0
cdef saw_int(self, object val):
self.sint_ = 1
def test(object val):
test_type(val)
def test_type(object val, Seen seen=Seen()):
print ('BEFORE:', seen.sint_)
val = int(val)
seen.saw_int(val)
print ('AFTER:', seen.sint_)
构建它并调用如下函数:
import test
import numpy as np
test.test(-1)
print('')
test.test(np.iinfo(np.uint64).max)
产生问题的输出:
INIT seen object
BEFORE: False
AFTER: True
BEFORE: True
AFTER: True
作为输出状态 - seen
对象不会在第二次test.test
调用中实例化。但与此同时,如果更改test_type
这样的声明:
cdef test_type(object val):
cdef Seen seen=Seen()
...
初始化发生在每次调用上。
所以2个问题:
- 为什么
test_type
的两种实现是不同的?据我从cython文档中记得,这两者是可以互换的。 - 我应该如何将
seen
对象传递给默认为初始化新对象的test_type
?如果 (..., Seen seen=Seen((( 不起作用?
定义函数时,函数的默认值将计算一次。如果每次调用 test_type
时都需要一个新的 Seen
实例,请执行以下操作:
def test_type(object val, Seen seen=None):
if seen is None:
seen = Seen()
print ('BEFORE:', seen.sint_)
val = int(val)
seen.saw_int(val)
print ('AFTER:', seen.sint_)
警告:我对cython不是很熟悉,所以可能缺少一个微妙之处。但这将是普通 Python 代码中的问题,我怀疑同样的问题也适用于这里。