Я использую пользовательский кодировщик 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
будет Enum
Примечание: python_type
— это abstractproperty
; transform_python
— это функция, которая принимает значение типа python_type
и возвращает что-то вроде тип допустим для сериализации bson.
Я пробовал это:
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.htmlhttp://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
, вы можете использовать issubclass(cls_encoder, TypeEncoder)
.
Если вы считаете, что ответ @gmds помог вам, вы можете рассмотреть что делать, когда кто-то отвечает на мой вопрос и как принять мой ответ
@ReblochonMasque спасибо за советы. Я принял этот ответ, но не могу проголосовать из-за отсутствия репутации.
Хорошо тебе, спасибо! Теперь вашего представителя должно быть достаточно, чтобы проголосовать.
Все еще нужно 2, хахаха, постараюсь не забыть проголосовать, когда получу 15, и вернуться сюда.
Ты прав, лол, я забыл создать экземпляр, чтобы проверить это. Спасибо за помощь! :D