【问题标题】:Unpickle class instances by interating over a list通过迭代列表来取消腌制类实例
【发布时间】:2016-08-16 20:48:29
【问题描述】:

我试图通过遍历包含所有类实例的列表(每个类实例在实例化时将自身附加到适当的列表)来取消保存在单独的 .pkl 文件中的各种类实例。

有效

# LOAD IN INGREDIENT INSTANCES
for each in il:
    with open('Ingredients/{}.pkl'.format(each), 'rb') as f:
        globals()[each] = pickle.load(f)

例如,一种成分是Aubergine

print(Aubergine)

输出:

Name:         Aubergine 
Price:        £1.00 
Portion Size: 1

但是,这不起作用

# LOAD IN RECIPE INSTANCES
for each in rl:
    with open('Recipes/{}.pkl'.format(each.name), 'rb') as f:
        globals()[each] = pickle.load(f)

我只能假设问题源于each.name 用于配方的文件名,而each 用于配料文件名。然而,这是故意的,因为食谱的 name 属性是为最终用户格式化的(即包含空格等)。我认为这可能是问题所在,但我不确定。

成分和配方类都使用:

def __repr__(self):
    return self.name

例如:

我有一个配方类实例SausageAubergineRagu,其中self.name'Sausage & Aubergine Ragu',它在rl 列表中。我试过单独测试这个:

输入:

rl

输出:

[Sausage & Aubergine Ragu]

所以我相信这段代码:

# LOAD IN RECIPE INSTANCES
for each in rl:
    with open('Recipes/{}.pkl'.format(each.name), 'rb') as f:
        globals()[each] = pickle.load(f)

...应该是这样的:

with open('Recipes/Sausage & Aubergine Ragu.pkl', 'rb') as f:
    globals()[SausageAubergineRagu] = pickle.load(f)

但尝试访问配方类实例会导致 NameError。

最后一点 - 请不要问我为什么要这样做。相反,帮助我解决和解决问题,这样我就可以让它发挥作用,并了解正在发生的事情。赞赏:)

【问题讨论】:

  • 为什么这个问题被否决了?

标签: python class filenames pickle


【解决方案1】:

您得到的NameError 是 Python 告诉您您正在尝试使用尚未定义的变量。

在此行中使用 SausageAubergineRagu 之前,您没有定义它:

globals()[SausageAubergineRagu] = pickle.load(f)

在您的第一个示例中,您正在向globals 添加键和值。您将配方实例 (each) 用作键,并将腌制数据用作值。

在第二个示例中,您尝试做同样的事情,但不是使用配方实例 (each) 作为键,而是使用未定义的 SausageAubergineRagu

Python 应该如何知道SausageAubergineRagu 是什么?如果你想让那条线工作,你需要先定义它,或者使用已经定义的东西,比如each,这就是你在另一个sn-p中所做的。

老实说,在globals 中使用自定义类的实例作为键对我来说似乎很奇怪(通常人们使用字符串),但既然您显然想让它工作,答案很简单:

在尝试将SausageAubergineRagu 用作字典中的键之前定义它。

【讨论】:

  • 我正在尝试定义它。这就是重点。它适用于成分类,但不适用于配方类。在我的问题中,我已经演示了成分类实例 Aubergine 已成功取消腌制的实例。
  • 好的,这就解释了我尝试在代码中编写的名称错误,但是当它仍在使用each 时它仍然不起作用。如果我运行代码并调用该类,则表示它未定义。有什么想法吗?
  • 可能是因为您将配方实例用作globals 中的键。尝试改用globals()[each.name] = pickle.load(f)。无论如何,使用字符串作为键更有意义。
  • 我不明白你的意思?我的想法是这样的,如有错误请指正。使用each 是因为列表中的每个都是类的实际实例;我只是从上一个会话中解开它。同样在我使用的示例中,each 将是类实例 SausageAubergineRagu,而 each.name 将是字符串“Sausage & Aubergine Ragu”,所以我无法调用它的属性,因为因为它会是一个字符串。
  • @JakeStokes 为什么要用类本身的实例作为key?你了解globals() 的工作原理吗?为什么不使用字符串"SausageAubergineRagu" 作为键,然后你可以在你的命名空间中像任何其他变量一样使用它。
猜你喜欢
  • 1970-01-01
  • 2020-07-22
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2018-09-02
相关资源
最近更新 更多