我正在使用pymongo自定义bson编码器。因为编码器不能被继承,所以需要为每个类创建它,所以我想为它动态创建一个编码器。
问题是基本编码器(TypeEncoder
)是从abc类创建的。当我试图使用以下代码创建类时:
from bson.codec_options import TypeEncoder
cls_encoder = type(f"Flag{cls.__name__}Encoder",
(TypeEncoder,),
{"transform_python": lambda self, value: value.code,
"python_type": property(lambda self: cls)})
结果会是
>> isinstance(cls_encoder, TypeEncoder)
False
>> type(cls_encoder)
<class 'abc.FlagAutoReplyContentTypeEncoder'>
>> super(cls_encoder)
<super: <class 'FlagAutoReplyContentTypeEncoder'>, NULL>
预期的结果应该是
>> isinstance(cls_encoder, TypeEncoder)
True
注意:
cls
变量将是枚举注意:
python_type
是一个abstractproperty
;transform_python
是一个接受python_type
类型的值并返回type is valid for bson serialization的函数。我试过这个:
class FlagBsonEncoder(TypeEncoder):
def transform_python(self, value):
return value.code
cls_encoder = type(f"Flag{cls.__name__}Encoder",
(FlagBsonEncoder,),
{"python_type": property(lambda self: cls)})
但结果还是一样:
>> isinstance(cls_encoder, TypeEncoder)
False
下面是如何使用自定义类型编码的官方示例:
http://api.mongodb.com/python/current/api/bson/codec_options.html
http://api.mongodb.com/python/current/examples/custom_type.html#custom-type-type-codec
最佳答案
我想你误解了isinstance
的作用。isinstance(cls_encoder, TypeEncoder)
询问类对象是否是cls_encoder
的实例。当然不是-这是一种类型!
您需要的是TypeEncoder
,它询问isinstance(cls_encoder(), TypeEncoder)
的实例是否也是cls_encoder
的实例,当然这必须是真的。
如果要检查类TypeEncoder
是否是cls_encoder
的子类,可以使用TypeEncoder
。