我正在使用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是一个abstractpropertytransform_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

10-06 10:54