代码之家  ›  专栏  ›  技术社区  ›  Digital Farmer

当字符串值已由冒号分隔时,将多行字符串转换为字典

  •  0
  • Digital Farmer  · 技术社区  · 3 年前

    我使用一个模块处理以下错误:

    class APIError(BetfairError):
        """
        Exception raised if error is found.
        """
    
        def __init__(
            self,
            response: Optional[dict],
            method: str = None,
            params: dict = None,
            exception: Exception = None,
        ):
            super(APIError, self).__init__(response, method, params, exception)
            self.response = response
            self.method = method
            self.params = params
            self.exception = exception
    
        def __str__(self):
            if self.response:
                error_data = self.response.get("error")
                return "%s \nParams: %s \nException: %s \nError: %s \nFull Response: %s" % (
                    self.method,
                    self.params,
                    self.exception,
                    error_data,
                    self.response,
                )
            else:
                return "%s \nParams: %s \nException: %s" % (
                    self.method,
                    self.params,
                    self.exception,
                )
    

    错误输出的stringvalue的多行模式已由冒号分隔:

    betfairlightweight.exceptions.APIError: SportsAPING/v1.0/listMarketBook 
    Params: {'marketIds': ['1.200293211'], 'priceProjection': {'priceData': ['EX_TRADED'], 'exBestOffersOverrides': {}, 'virtualise': True, 'rolloverStakes': False}} 
    Exception: None 
    Error: {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '...........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}} 
    Full Response: {'jsonrpc': '2.0', 'error': {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '..........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}}, 'id': 1}
    

    因此,我可以访问这些值,而不管它们的位置如何,我将字符串转换为如下字典:

    
    # except Exception as e:
    #     e.__str__()
    
    e = """betfairlightweight.exceptions.APIError: SportsAPING/v1.0/listMarketBook 
    Params: {'marketIds': ['1.200293211'], 'priceProjection': {'priceData': ['EX_TRADED'], 'exBestOffersOverrides': {}, 'virtualise': True, 'rolloverStakes': False}} 
    Exception: None 
    Error: {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '...........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}} 
    Full Response: {'jsonrpc': '2.0', 'error': {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '..........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}}, 'id': 1}"""
    
    fs = []
    nfs = []
    for row in e.split('\n'):
        fs.append(row[:row.find(':')] + ':')
        nfs.append('\'' + row[:row.find(':')] + '\'' + ':')
    for x, y in zip(fs, nfs):
        e = e.replace(x, y)
    for z in e.split('\n'):
        if (': {' not in z) and (': None' not in z):
            e = e.replace(z, z.replace(': ', ': \'').strip() + '\'')
    
    for_dict = eval('{' + e.replace('\n', ',') + '}')
    
    print(for_dict)
    
    # Get SportsAPING/v1.0/listMarketBook value
    print(for_dict['betfairlightweight.exceptions.APIError'])
    
    # Get ABC-0025 value
    print(for_dict['Error']['message'])
    
    # Get 2.0 value
    print(for_dict['Full Response']['jsonrpc'])
    
    # Get ['EX_TRADED'] value
    print(for_dict['Params']['priceProjection']['priceData'])
    

    有没有一种更像Python的方法或模块来处理这种类型的多行字符串,以便能够以更干净、更专业的方式生成此词典?

    2 回复  |  直到 3 年前
        1
  •  1
  •   Joran Beasley    3 年前

    这感觉有点主观,但下面是我将如何实现它(在花了一两分钟的时间之后)

    import ast
    def line_to_dict_entry(line):
        key,value = line.strip().split(":",1)
        try:
            # try and parse it to a base pyobject
            value = ast.literal_eval(value.strip())
        except Exception as e:
            # just let it be a string
            value = value.strip()
        return key,value
    
    data = dict(line_to_dict_entry(l) for l in e.splitlines(False))
    
    print(data)
    
        2
  •  0
  •   BeRT2me    3 年前
    import re
    from ast import literal_eval
    
    e = """betfairlightweight.exceptions.APIError: SportsAPING/v1.0/listMarketBook 
    Params: {'marketIds': ['1.200293211'], 'priceProjection': {'priceData': ['EX_TRADED'], 'exBestOffersOverrides': {}, 'virtualise': True, 'rolloverStakes': False}} 
    Exception: None 
    Error: {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '...........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}} 
    Full Response: {'jsonrpc': '2.0', 'error': {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '..........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}}, 'id': 1}"""
    
    
    data = dict(x.split(':', 1) for x in e.splitlines())
    data = {k.strip():literal_eval(v) if '{' in v else v.strip() for k,v in data.items()}
    print(data)
    

    输出:

    {'betfairlightweight.exceptions.APIError': 'SportsAPING/v1.0/listMarketBook', 'Params': {'marketIds': ['1.200293211'], 'priceProjection': {'priceData': ['EX_TRADED'], 'exBestOffersOverrides': {}, 'virtualise': True, 'rolloverStakes': False}}, 'Exception': 'None', 'Error': {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '...........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}}, 'Full Response': {'jsonrpc': '2.0', 'error': {'code': -32099, 'message': 'ANGX-0006', 'data': {'APINGException': {'requestUUID': '..........', 'errorCode': 'UNEXPECTED_ERROR', 'errorDetails': ''}, 'exceptionname': 'APINGException'}}, 'id': 1}}
    

    漂亮的输出:

    import json
    
    print(json.dumps(data, indent=3))
    
    ...
    
    {
       "betfairlightweight.exceptions.APIError": "SportsAPING/v1.0/listMarketBook",
       "Params": {
          "marketIds": [
             "1.200293211"
          ],
          "priceProjection": {
             "priceData": [
                "EX_TRADED"
             ],
             "exBestOffersOverrides": {},
             "virtualise": true,
             "rolloverStakes": false
          }
       },
       "Exception": "None",
       "Error": {
          "code": -32099,
          "message": "ANGX-0006",
          "data": {
             "APINGException": {
                "requestUUID": "...........",
                "errorCode": "UNEXPECTED_ERROR",
                "errorDetails": ""
             },
             "exceptionname": "APINGException"
          }
       },
       "Full Response": {
          "jsonrpc": "2.0",
          "error": {
             "code": -32099,
             "message": "ANGX-0006",
             "data": {
                "APINGException": {
                   "requestUUID": "..........",
                   "errorCode": "UNEXPECTED_ERROR",
                   "errorDetails": ""
                },
                "exceptionname": "APINGException"
             }
          },
          "id": 1
       }
    }