我可以在运行时在 cython 扩展 (cdef class) 属性中使用派生的 class 吗?
Can I use a derived class in a cython extention (cdef class) attribute at runtime?
我有一个惰性字典(类似于工厂)在我的 python 库中构建单例,我只存储类型并仅在需要对象时创建实例(创建对象很耗时) ):
(mypythonlib.py)
class LazyDict(dict):
def __init__(self):
super().__init__()
def __getitem__(self,key):
import inspect
objOrType = dict.__getitem__(self, key)
if inspect.isclass(objOrType):
objOrType = objOrType()
dict.__setitem__(self,key,objOrType)
return objOrType
integrationRuleFromPython = LazyDict()
integrationRuleFromPython["string1"] = myheavyclass1
integrationRuleFromPython["string2"] = myheavyclass2
...
然后我想在 cython 扩展中使用这本词典。
我的 cython 扩展看起来是这样的:(integration.pyx)
from mypythonlib import integrationRuleFromPython
cdef class IntegralCpp():
cdef dict integrationRule
def __init__(self):
self.integrationRule = integrationRuleFromPython
...
我的扩展编译正确,但在运行时获取:
文件 "integration.pyx",第 76 行,在 integration.IntegralCpp.init TypeError: 预期字典,得到 LazyDict
我可以使用 python 派生的 class 在 cython 扩展中设置属性吗?
不,如果你用cdef
声明一个类型,它必须是一个确切的类型。来自 documentation:
Also, the Python types list
, dict
, tuple
, etc. may be used for static typing, as well as any user defined Extension Types. For example:
cdef list foo = []
This requires an exact match of the class, it does not allow subclasses. This allows Cython to optimize code by accessing internals of the builtin class, which is the main reason for declaring builtin types in the first place.
旁白:在 PEP-484 类型注释中,这称为“不变性”。
我有一个惰性字典(类似于工厂)在我的 python 库中构建单例,我只存储类型并仅在需要对象时创建实例(创建对象很耗时) ):
(mypythonlib.py)
class LazyDict(dict):
def __init__(self):
super().__init__()
def __getitem__(self,key):
import inspect
objOrType = dict.__getitem__(self, key)
if inspect.isclass(objOrType):
objOrType = objOrType()
dict.__setitem__(self,key,objOrType)
return objOrType
integrationRuleFromPython = LazyDict()
integrationRuleFromPython["string1"] = myheavyclass1
integrationRuleFromPython["string2"] = myheavyclass2
...
然后我想在 cython 扩展中使用这本词典。 我的 cython 扩展看起来是这样的:(integration.pyx)
from mypythonlib import integrationRuleFromPython
cdef class IntegralCpp():
cdef dict integrationRule
def __init__(self):
self.integrationRule = integrationRuleFromPython
...
我的扩展编译正确,但在运行时获取:
文件 "integration.pyx",第 76 行,在 integration.IntegralCpp.init TypeError: 预期字典,得到 LazyDict
我可以使用 python 派生的 class 在 cython 扩展中设置属性吗?
不,如果你用cdef
声明一个类型,它必须是一个确切的类型。来自 documentation:
Also, the Python types
list
,dict
,tuple
, etc. may be used for static typing, as well as any user defined Extension Types. For example:cdef list foo = []
This requires an exact match of the class, it does not allow subclasses. This allows Cython to optimize code by accessing internals of the builtin class, which is the main reason for declaring builtin types in the first place.
旁白:在 PEP-484 类型注释中,这称为“不变性”。