【问题标题】:JavaScript JSON reviver in PythonPython 中的 JavaScript JSON reviver
【发布时间】:2022-12-03 18:13:48
【问题描述】:

我在将 JavaScript sn-p 转换为 Python 时遇到问题。

JavaScript 代码如下所示:

const reviver = (_key, value) => {
  try {
    return JSON.parse(value, reviver);
  } catch {
    if(typeof value === 'string') {
      const semiValues = value.split(';');
      if(semiValues.length > 1) {
        return stringToObject(JSON.stringify(semiValues));
      }
      const commaValues = value.split(',');
      if(commaValues.length > 1) {
        return stringToObject(JSON.stringify(commaValues));
      }
    }
    const int = Number(value);
    if(value.length && !isNaN(int)) {
      return int;
    }
    return value;
  }
};

const stringToObject = (str) => {
  const formatted = str.replace(/"{/g, '{').replace(/}"/g, '}').replace(/"\[/g, '[').replace(/\]"/g, ']').replace(/\\"/g, '"');
  return JSON.parse(formatted, reviver);
};

该功能的目标是:

  • 作为数字的字符串值被解析
  • 使用这些规则解析 json 字符串值
  • "499,504;554,634"这样的字符串值应该被解析为[(499, 504), (554, 634)]

我试过使用JSONDecoder

import json

def object_hook(value):
    try:
        return json.loads(value)
    except:
        if(isinstance(value, str)):
            semiValues = value.split(';')
            if(len(semiValues) > 1):
                return parse_response(json.dumps(semiValues))
            commaValues = value.split(',')
            if(commaValues.length > 1):
                return parse_response(json.dumps(commaValues))
        try:
            return float(value)
        except ValueError:
            return value

def parse_response(data: str):
    formatted = data.replace("\"{", "{").replace("}\"", '}').replace("\"[", '[').replace("]\"", ']').replace("\\\"", "\"")
    return json.load(formatted, object_hook=object_hook)

【问题讨论】:

    标签: javascript python json reviver-function


    【解决方案1】:

    我通过遍历值并相应地解析它们来解决我的问题

    def parse_value(value):
        if(isinstance(value, str)):
            try:
                data = json.loads(value)
                if(isinstance(data, dict)):
                    return {k: parse_value(v) for k, v in data.items()}
                if(isinstance(data, list)):
                    return list(map(parse_value, data))
                if(isinstance(data, str)):
                    return parse_value(data)
                return data
            except:
                pass
            semi_values = value.split(';')
            if(len(semi_values) > 1):
                return list(map(parse_value, semi_values))
            comma_values = value.split(',')
            if(len(comma_values) > 1):
                return list(map(parse_value, comma_values))
            if(value.replace('.','',1).isdigit()):
                return int(value)
        if(isinstance(value, dict) or isinstance(value, list)):
            return parse_value(json.dumps(value))
        return value
    

    【讨论】:

      【解决方案2】:

      您的 Python 代码看起来走在正确的轨道上,但存在一些问题。首先,您在检查commaValues 的长度是否大于1 的if 语句中使用commaValues.length 而不是len(commaValues)。其次,json.load() 需要一个类似文件的对象作为它的第一个参数,而不是字符串。您可以改用 json.loads() 来解析 JSON 字符串。

      下面是我将如何用 Python 编写代码:

      import json
      
      def reviver(key, value):
        try:
          return json.loads(value, reviver=reviver)
        except:
          if isinstance(value, str):
            semiValues = value.split(';')
            if len(semiValues) > 1:
              return stringToObject(json.dumps(semiValues))
            commaValues = value.split(',')
            if len(commaValues) > 1:
              return stringToObject(json.dumps(commaValues))
      
          try:
            return int(value)
          except ValueError:
            return value
      
      def stringToObject(str):
        formatted = str.replace('"{', '{').replace('}"', '}').replace('"[', '[').replace(']"', ']').replace('\"', '"')
        return json.loads(formatted, reviver=reviver)
      

      请注意,我还更改了尝试将字符串转换为数字的 try 语句,以使用 int() 而不是 float() 将值解析为整数而不是浮点数。我还更改了函数和变量名称以遵循使用下划线分隔的小写单词的 Python 约定(例如 string_to_object 而不是 stringToObject)。

      【讨论】:

        【解决方案3】:

        这段代码对你有用吗?

        def reviver(_key, value):
            try:
                return json.loads(value, object_hook=reviver)
            except:
                if type(value) == str:
                    semi_values = value.split(';')
                    if len(semi_values) > 1:
                        return string_to_object(json.dumps(semi_values))
                    comma_values = value.split(',')
                    if len(comma_values) > 1:
                        return string_to_object(json.dumps(comma_values))
                int_val = int(value)
                if len(value) and not isinstance(int_val, int):
                    return int_val
                return value
        
        def string_to_object(str):
            formatted = str.replace('"{', '{').replace('}"', '}').replace('"[', '[').replace(']"', ']').replace('\"', '"')
            return json.loads(formatted, object_hook=reviver)
        

        【讨论】:

        • 它不起作用。看起来 object_hook 函数只有一个参数。如果我删除 _key,我会得到这个错误:``` int() 参数必须是一个字符串,一个类似字节的对象或一个实数,而不是'dict'```
        • not isinstance(int_val, int) 在您的代码中是不可能的。那应该是什么意思?
        • 你能提供一个预期输入/输出的例子吗?
        • 这是一个示例input,它是output
        • 粘贴已被删除
        猜你喜欢
        • 1970-01-01
        • 2017-02-05
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        • 2011-01-10
        • 2020-02-16
        • 2012-05-22
        • 2018-04-02
        相关资源
        最近更新 更多