【问题标题】:Is it possible to get isinstance or similar type-checking to work with my pickled classes? [duplicate]是否可以让 isinstance 或类似的类型检查与我的腌制类一起使用? [复制]
【发布时间】:2013-04-22 10:52:05
【问题描述】:

我有一个非常烦人的错误,我终于找到了它。

我使用(或更准确地说,已经使用过)一个独立的脚本来创建对象存储,然后我腌制这个数据结构。然后,我可以在每次程序运行时使用反序列化数据初始化我的主程序。

但是,如果我使用类型检查,这将成为一个问题。在我做 pickle.dump() 并得到这个数据结构之后,我设置了它,以便我尝试检查一个对象的类型。不幸的是,我唯一可以检查的就是我的类的 new 重新加载,Python 认为这是不同的。

DEBUG: 我正在检查对象:>> Fixture {name: 'Front Desk', location: '0', desc: 'The front desk has a sign that read...'} 调试:通用游戏对象:>> GameObject {name: '', location: 'None', desc: '...' }

(您可以看到对象表示看起来非常相似。这是因为一个从另一个继承__repr__,即应该是它的一个实例。)

调试:我正在类型检查的对象类型:{class 'chimai.chimai.objects.fix.Fixture'}
调试:通用游戏对象的类型:{class 'objects.game_object.GameObject'}
调试:我正在类型检查的对象的 MRO:({class 'chimai.chimai.objects.fix.Fixture'},{class 'chimai.chimai.objects.game_object.GameObject'},{type 'object'} )
调试:通用游戏对象的 MRO:({class 'objects.game_object.GameObject'}, {type 'object'})

(GameObject 类的标识符略有不同;这来自我最初运行独立脚本的位置。)

调试:腌制夹具类型的 ID:173671604
调试:在我的主程序中重新加载的夹具类型 ID:149507748

最终结果是,我根本想不出一种方法来检查我的腌制数据。除非有人有任何天才的建议,否则我想我会是鸭子打字。

【问题讨论】:

  • 你没有检查同一个对象根本。您将fix.Fixture 实例与game_object.GameObject 进行比较。显然,这些不是同一类型的对象。我认为您误解了您的代码的作用,这与 Pickle 无关
  • 也许我不够清楚。 isinstance(),给定 fix.Fixture 的实例,类 game_object.GameObject 返回 False。这就是我研究这两个的原因。
  • fix.Fixture 应该是game_object.GameObject 的子类吗?
  • 看看我刚刚发布的 MRO。 fix.Fixture 确实是game_object.GameObject 的直接子类。但是,那个特定的fix.Fixture 实例是与我比较的game_object.GameObject 不同的子类。例如,请参阅 stackoverflow.com/questions/620844/…stackoverflow.com/questions/15876395/…
  • 这是因为在一个会话中进行酸洗并在另一个会话中使用数据时,您实际上已经加载了两个不同的时间类,这会分别创建一个不同的对象。见:stackoverflow.com/a/620866/1151229

标签: python class pickle typechecking isinstance


【解决方案1】:

AFAIK,以任何简单的方式都不可能;类型检查与在不同会话中腌制的数据不兼容。在类型检查方面,我不是狂热者,但我喜欢有效的方法。

【讨论】:

  • Pickle 应该给你相同的类型;它使用与原始相同的类引用(模块-> 类定义)。您的代码还有其他问题。
  • 一个类是一个对象。当你重新加载一个模块时,在不同的会话中,你创建了一个不同的类对象。例如,参见stackoverflow.com/a/620866/1151229
  • 如果您在不同的会话中指的是新的口译员,那么您的诊断是错误的。在该新会话中,pickle 将使用与您用于测试isinstance() 的类相同的类来取消腌制。除非在那个新的会话中,类在此期间被交换了。
  • 我真的不知道会话(特别是解释器)实际上与它有什么直接关系。我只是想强调一个不同会话的事实,因为我的酸洗的特定用例必然涉及在一个脚本中加载一次类,然后在另一个脚本中再次加载它。
  • 抱歉,您的诊断还是有误的。做一个简单的测试用例。在一个模块中创建两个类,一个继承自另一个。测试isinstance() 是否有效。然后腌制这些,并在新的 Python 解释器会话中再次加载它们。再次测试 isintance 测试。 它会工作
猜你喜欢
  • 1970-01-01
  • 2018-08-15
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 2012-10-23
相关资源
最近更新 更多