动态创建一个从ABC类派生的类

时间:2019-05-29 09:26:49

标签: python mongodb

我正在使用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_typeabstractpropertytransform_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

1 个答案:

答案 0 :(得分:1)

我认为您误解了isinstance的作用。

isinstance(cls_encoder, TypeEncoder)询问类对象 cls_encoder是否是TypeEncoder的实例。当然不是-它是类型

您想要的是isinstance(cls_encoder(), TypeEncoder),它询问cls_encoder的实例是否也是TypeEncoder的实例,当然这必须是真实的。

如果要检查类cls_encoder是否是TypeEncoder子类,则可以使用issubclass(cls_encoder, TypeEncoder)