【问题标题】:python cannot marshal <class 'decimal.Decimal'> objectspython 无法编组 <class 'decimal.Decimal'> 对象
【发布时间】:2015-08-15 07:48:04
【问题描述】:

我将我的操作系统更新到 Centos 7。现在我有了 Python 2.7。

以下代码在 Python 2.6 中可以使用,但现在无法使用。

OS: Centos 7
Python 2.7.5
Apache/2.4.6

我的 do_POST 是:

def do_POST(self):
    """Handles the HTTP POST request.

    Attempts to interpret all HTTP POST requests as XML-RPC calls,
    which are forwarded to the _dispatch method for handling.
    """

    try:
        # get arguments
        data = self.rfile.read(int(self.headers["content-length"]))
        params, method = xmlrpclib.loads(data)

        # generate response
        try:
            response = self._dispatch(method, params)
            # wrap response in a singleton tuple
            response = (response,)
        except XMLRPCFault:
            # report exception back to server
            response = xmlrpclib.dumps(
                xmlrpclib.Fault(1, "%s" % (sys.exc_info()[1]))
                )
        else:
            response = xmlrpclib.dumps(response, methodresponse=1)
    except:
        logException(LOG_ERROR,"XMLRPCServer")
        # internal error, report as HTTP server error
        self.send_response(500)
        self.end_headers()
    else:
        # got a valid XML RPC response
        self.send_response(200)
        self.send_header("Content-type", "text/xml")
        self.send_header("Content-length", str(len(response)))
        self.end_headers()
        self.wfile.write(response)

        # shut down the connection
        self.wfile.flush()
        self.connection.shutdown(1)

错误是:

2015/08/15-11:49:36 XMLRPCServer
Traceback (most recent call last):
  File "/usr/local/IBSng/core/server/xmlrpcserver.py", line 53, in do_POST
    response = xmlrpclib.dumps(response, methodresponse=1)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1085, in dumps
    data = m.dumps(params)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 632, in dumps
    dump(v, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 654, in __dump
    f(self, value, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 735, in dump_struct
    dump(v, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 654, in __dump
    f(self, value, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 735, in dump_struct
    dump(v, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 654, in __dump
    f(self, value, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 735, in dump_struct
    dump(v, write)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 646, in __dump
    raise TypeError, "cannot marshal %s objects" % type(value)
TypeError: cannot marshal <class 'decimal.Decimal'> objects

【问题讨论】:

    标签: python


    【解决方案1】:

    xmlrpclib 模块不支持开箱即用的decimal.Decimal 对象,不。

    您有两个选择:首先将 Decimal 对象转换为浮点数,或者扩展编组器以显式处理 Decimal 对象。

    转换Decimal 对象很简单:

    from decimal import Decimal
    
    # ..
    def convert_decimal_to_float(ob):
        if isinstance(ob, Decimal):
            return float(ob)
        if isinstance(ob, (tuple, list)):
            return [convert_decimal_to_float(v) for v in ob]
        if isinstance(ob, dict):
            return {k: convert_decimal_to_float(v) for k, v in ob.iteritems()}
        return ob
    
    response = self._dispatch(method, params)
    response = (convert_decimal_to_float(response),)
    

    为库添加支持如下所示:

    from xmlrpclib import Marshaller
    from decimal import Decimal
    
    def dump_decimal(self, value, write):
        write("<value><double>")
        write(str(value))
        write("</double></value>\n")
    
    Marshaller.dispatch[Decimal] = dump_decimal
    

    【讨论】:

    • 或第三个选项——先将Decimal对象转换为a字符串,然后再转换回Decimal
    • @MarkChackerian:但这需要 XML-RPC 服务器端的支持才能接受这样的字符串值。
    • 是的——如果您可以更改服务器端,这只是一个可行的选择。
    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2022-01-07
    • 2019-03-18
    • 2019-05-20
    相关资源
    最近更新 更多