我正在使用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
答案 0 :(得分:1)
我认为您误解了isinstance
的作用。
isinstance(cls_encoder, TypeEncoder)
询问类对象 cls_encoder
是否是TypeEncoder
的实例。当然不是-它是类型!
您想要的是isinstance(cls_encoder(), TypeEncoder)
,它询问cls_encoder
的实例是否也是TypeEncoder
的实例,当然这必须是真实的。
如果要检查类cls_encoder
是否是TypeEncoder
的子类,则可以使用issubclass(cls_encoder, TypeEncoder)
。