内部类的序列化
我有一个叫做 model
的Python模块,里面大致包含以下内容:
class Database:
class Publiation(object):
pass
class Article(Publication):
pass
class Book(Publication):
pass
class AnotherDatabase:
class Seminar(object):
pass
...
我把数据库中的对象定义成类,并把这些类放在一个主类下面,这样可以更清晰地组织它们。这些对象是从一个很大的XML文件中解析出来的,这个过程需要一些时间。我想把导入的对象进行“打包”,这样下次加载的时候就能更快。
但是我遇到了一个错误:
pickle.PicklingError: Can't pickle : it's not found as project.model.Article
现在这个类是 project.model.Article
,而不是之前定义的 project.model.Database.Article
。我能解决这个错误,同时保持类的嵌套结构吗?把类嵌套在一起组织,这样做是个坏主意吗?
2 个回答
5
当我们创建一个内部类时,解释器并不知道这个类是在哪个外部类里面定义的,因为这个信息并没有被记录下来。这就是为什么在使用pickle的时候,它不知道去哪里找Article这个类。
由于这个原因,使用内部类会出现很多问题,不仅仅是在使用pickle的时候。如果在模块范围内有同名的类,就会造成很多混淆,因为没有简单的方法来区分这两种类型(比如在使用repr或者调试的时候)。
因此,通常情况下,除非你有非常好的理由,否则最好避免在Python中使用嵌套类。
2
把你的类保持在一个简单的结构里,确实会简单很多。你也可以用包来把这些类放在一起。
另外,还有一个叫做 cerealizer
的替代序列化工具,我觉得它可以处理嵌套的类。在反序列化之前,你需要先把这些类注册到这个工具里。我之前用过这个工具,当 pickle
不够用的时候(还有一些和类相关的问题),它的表现很好!