2

我无法检索存储在 Maya 中的确切JSON 字符串转储 ( ) 。json.dumpsfileInfo

>>> import pymel.core as pc
>>> json.dumps({'foo': 123})
'{"foo": 123}'
>>> pc.fileInfo['foo'] = json.dumps({'foo': 123})
>>> pc.fileInfo['foo']
u'{\\"foo\\": 123}'
>>> json.loads(pc.fileInfo['foo']) # this produces an error because of the escape sequence
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\Program Files\Autodesk\Maya2011\bin\python26.zip\json\__init__.py", line 307, in loads

  File "c:\Program Files\Autodesk\Maya2011\bin\python26.zip\json\decoder.py", line 319, in decode
  File "c:\Program Files\Autodesk\Maya2011\bin\python26.zip\json\decoder.py", line 336, in raw_decode
  File "c:\Program Files\Autodesk\Maya2011\bin\python26.zip\json\scanner.py", line 55, in iterscan
  File "c:\Program Files\Autodesk\Maya2011\bin\python26.zip\json\decoder.py", line 171, in JSONObject
ValueError: Expecting property name: line 1 column 1 (char 1)

问题是当 Maya 存储一个值时,它确保它被正确转义。但是当这个字符串被检索到它的格式错误时json.loads。我怎样才能解决这个问题?

我基本上在寻找的是无法逃脱的东西序列的东西?到目前为止,我还没有找到任何可以做到这一点的东西。

MEL 与 C 有很多相似之处,因此转义序列与 C 的大部分相同,如上所示。

4

2 回答 2

1

确保完整地进出 fileInfo 的最佳方法是在输入时对其进行 base64 编码并在输出时对其进行解码。Maya 不会为您执行此操作,并且它提供的转义功能如您所见,很奇怪。

这是我用的;它使用 yaml 但你应该能够在 json 中交换没问题。我已经用它来按照您想要的方式保存 yaml 数据。

'''
mayaPersist - namespace for functions related to storing data in fileInfo objects inside the current Maya file

I've tested this (a little) with as many as 100,000 integers - it works but it's slooow at that size
< 1000 values seems imperceptible
'''

import yaml
import base64
from  maya.cmds import fileInfo
import itertools

def save(key, value):
    '''
    save the specified value as a base64 encoded yaml dunp at key 'key'
    '''
    encoded =encode(value)
    fileInfo(key, encoded)

def load(key):
    '''
    return the value stored at 'key', or None if the value can't be found

    @note it is possible to store a 'None' in the value, so this doesn't prove that the key does not exist !
    '''
    answer = fileInfo(key, q=True)
    if not answer:
        return None
    return decode(answer[0])

def exists(key):
    '''
    returns true if the specified key exists
    '''
    answer = fileInfo(key, q=True)
    return len(answer) != 0

def ls():
    '''
    a generator that returns all of the key-value pairs in this file's fileInfo

    @note:  these are not decoded, because they contain a mix of native stirngs and b64 values
    '''
    all_values = fileInfo(q=True)
    keys = itertools.islice(all_values, 0, None, 2)
    values = itertools.islice(all_values, 1, None, 2)
    return itertools.izip(keys, values)


def delete(key):
    '''
    remove the key and any data stored with it from this file
    '''
    fileInfo(rm=key)

def decode(value):
    '''
    convert a base64'ed yaml object back into a maya object

    if the object is not encoded (eg, one of the default string values) return it untouched
    '''
    try:
        val = base64.b64decode(value)
        return yaml.load(val)
    except TypeError:  
        return value



def encode (value):
    '''
    return the supplied value encoded into base64-packed YAML dump
    '''
    return  base64.b64encode(yaml.dump(value))
于 2014-03-29T07:48:22.657 回答
1

@theodox 的答案可能是正确的。但是如果你知道 json 字符串会被转义。您可以简单地取回字符串的原始未转义版本。

mystring.decode('unicode_escape')

所以在上述情况下,反序列化存储信息的正确方法是:

json.loads(pc.fileInfo['foo'].decode('unicode_escape'))

不过它看起来有点难看,所以你可以把它放在一个函数中。

def safe_json_loads(str):
    return json.loads(str.decode('unicode_escape'))


data = safe_json_loads(pc.fileInfo['foo'])

干杯,

于 2014-03-29T08:01:25.127 回答