Marshmallow:如何重写 python class 的构造函数?
Marshmallow: How can I override this python class's constructor?
下面是我在基于 SQLAlchemy 的应用程序中使用的 python marshmallow 序列化程序。
import simplejson
from marshmallow import Schema
class MySerializer(Schema):
class Meta:
json_module = simplejson
fields = ('field1', 'field2', 'field3')
field3 = fields.Method('get_field3')
def get_field3(self, this_obj):
return "Hello"
我是这样称呼这个序列化程序的:
my_argument = 1
items=MySerializer(documents=list_of_my_objects, many=True).data
现在,我想更改序列化程序,使其接受一个额外的参数(我将传入 my_argument
),如果该参数的值为 1,则 return "Goodbye"
代替 "Hello"
。我该怎么做?
特别是,我不知道如何将参数传递给这个 marshamallow 模式,以便它可以从内部获得get_field3
。我知道我需要覆盖 __init__()
方法。但我不确定它应该是什么样子。我尝试了以下方法,但没有用:
def __init__(self, documents, many, my_arg):
self.my_arg = my_arg
super(Schema, self).__init__(documents, many=many)
def get_field3(self, this_obj):
self.my_arg == 1:
return "Goodbye"
else:
return "Hello"
这是我得到的堆栈跟踪:
my_project/my_models/serializers.pyc in __init__(self, documents, many, my_arg)
---> 25 super(Schema, self).__init__(documents, many=many)
my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in __init__(self, obj, extra, only, exclude, prefix, strict, many, skip_missing, context)
--> 273 self._update_fields(self.obj, many=many)
my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in _update_fields(self, obj, many)
--> 636 ret = self.__filter_fields(field_names, obj, many=many)
my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in __filter_fields(self, field_names, obj, many)
--> 683 attribute_type = type(obj_dict[key])
TypeError: list indices must be integers, not str
只需从 kwargs 中弹出添加的 arg 以避免任何错误(您可以将任何 kwargs 传递给以这种方式重新定义的方法):
class MySerializer(Schema):
# ...
def __init__(self, *args, **kwargs):
self.my_arg = kwargs.pop('my_arg') if 'my_arg' in kwargs else None
super(Schema, self).__init__(*args, **kwargs)
现在您可以传递自定义 kwarg(关键字 参数,而不是位置参数)来创建对象:
MySerializer(documents=list_of_my_objects, many=True, my_arg=1)
下面是我在基于 SQLAlchemy 的应用程序中使用的 python marshmallow 序列化程序。
import simplejson
from marshmallow import Schema
class MySerializer(Schema):
class Meta:
json_module = simplejson
fields = ('field1', 'field2', 'field3')
field3 = fields.Method('get_field3')
def get_field3(self, this_obj):
return "Hello"
我是这样称呼这个序列化程序的:
my_argument = 1
items=MySerializer(documents=list_of_my_objects, many=True).data
现在,我想更改序列化程序,使其接受一个额外的参数(我将传入 my_argument
),如果该参数的值为 1,则 return "Goodbye"
代替 "Hello"
。我该怎么做?
特别是,我不知道如何将参数传递给这个 marshamallow 模式,以便它可以从内部获得get_field3
。我知道我需要覆盖 __init__()
方法。但我不确定它应该是什么样子。我尝试了以下方法,但没有用:
def __init__(self, documents, many, my_arg):
self.my_arg = my_arg
super(Schema, self).__init__(documents, many=many)
def get_field3(self, this_obj):
self.my_arg == 1:
return "Goodbye"
else:
return "Hello"
这是我得到的堆栈跟踪:
my_project/my_models/serializers.pyc in __init__(self, documents, many, my_arg)
---> 25 super(Schema, self).__init__(documents, many=many)
my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in __init__(self, obj, extra, only, exclude, prefix, strict, many, skip_missing, context)
--> 273 self._update_fields(self.obj, many=many)
my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in _update_fields(self, obj, many)
--> 636 ret = self.__filter_fields(field_names, obj, many=many)
my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in __filter_fields(self, field_names, obj, many)
--> 683 attribute_type = type(obj_dict[key])
TypeError: list indices must be integers, not str
只需从 kwargs 中弹出添加的 arg 以避免任何错误(您可以将任何 kwargs 传递给以这种方式重新定义的方法):
class MySerializer(Schema):
# ...
def __init__(self, *args, **kwargs):
self.my_arg = kwargs.pop('my_arg') if 'my_arg' in kwargs else None
super(Schema, self).__init__(*args, **kwargs)
现在您可以传递自定义 kwarg(关键字 参数,而不是位置参数)来创建对象:
MySerializer(documents=list_of_my_objects, many=True, my_arg=1)