这是我在Python中的代码:

parser = argparse.ArgumentParser()
parser.add_argument('--use_model', type=str, help='model location', required=True)
parser.add_argument('--model_dim', type=int, help='model dimension of words', required=True)
args = parser.parse_args()
f = open(args.use_model, "rb")
f.seek(0)
trained_model = pickle.load(f)

我在最后一行收到_pickle.UnpicklingError: could not find MARK错误。

在这个问题上:

_pickle.UnpicklingError: could not find MARK

它说f.seek(0)解决了问题,但在我看来,它没有解决。

最佳答案

查看带下划线的_pickle模块(用C编写)的源代码,只有一个地方会出现这种错误:

static Py_ssize_t
marker(UnpicklerObject *self)
{
    Py_ssize_t mark;

    if (self->num_marks < 1) {
        PickleState *st = _Pickle_GetGlobalState();
        PyErr_SetString(st->UnpicklingError, "could not find MARK");
        return -1;
    }
...
}
在内部,pickle模块使用标记堆栈来解开容器对象,而num_marks指示其中有多少个对象。通过初始化Unpickler函数,将num_marks设置为0,然后在将新标记压入标记堆栈时递增。
发生此错误的一种可能方法是更改​​FRAME操作码(指示帧开始的值)或MARK操作码。假设我们使用协议(protocol)4(从此版本的pickle具有二进制框架功能开始),您可以在pep 3154中阅读更多内容。这个想法很简单明了-将所有内容分成块(框架)并标记每个框架的边界。让我们深入了解它。
考虑以下示例:
import pickle
data = {"fruits": ["apple", "banana", "pineapple"] }

with open("data.pickle", 'wb') as f:
    # Pickle the 'data' dictionary using the highest protocol available.
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
让我们用pickletools来研究一下:
python -m pickletools data.pickle
    0: \x80 PROTO      5
    2: \x95 FRAME      46
   11: }    EMPTY_DICT
   12: \x94 MEMOIZE    (as 0)
   13: \x8c SHORT_BINUNICODE 'fruits'
   21: \x94 MEMOIZE    (as 1)
   22: ]    EMPTY_LIST
   23: \x94 MEMOIZE    (as 2)
   24: (    MARK
   25: \x8c     SHORT_BINUNICODE 'apple'
   32: \x94     MEMOIZE    (as 3)
   33: \x8c     SHORT_BINUNICODE 'banana'
   41: \x94     MEMOIZE    (as 4)
   42: \x8c     SHORT_BINUNICODE 'pineapple'
   53: \x94     MEMOIZE    (as 5)
   54: e        APPENDS    (MARK at 24)
   55: s    SETITEM
   56: .    STOP
highest protocol among opcodes = 4
这里的FRAME(0x95)表示新帧的开始位置,而MARK('(')表示容器对象的开始,这些值由协议(protocol)指定(这是实现的细节)。
首先,我看一下pickle文件的内容,总结一下,问题原因可能是:
  • 该文件已损坏。
  • 文件指针未指向文件的开头,很可能可以通过f.seek(0)进行修复,请参见_pickle.UnpicklingError: could not find MARK
    ...

  • 找到了另一个原因?随时编辑答案。

    关于python - 找不到MARK,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51560625/

    10-13 05:20