代码之家  ›  专栏  ›  技术社区  ›  Mei Zhang

清除使用多个pickler保存的数据的干净方法。转储呼叫

  •  1
  • Mei Zhang  · 技术社区  · 8 年前

    取消勾选使用多个pickler保存的数据。dump calls,我们需要相同数量的调用来取消pickler。负载一种快速而肮脏的方法是尝试以下块:

    with open("data.pk", "wb") as f:
        pickler = pickle.Pickler(f)
        pickler.dump("message1")
        pickler.dump("message2")
        pickler.dump("message3")
    
    with open("data.pk", "rb") as f:
        unpickler = pickle.Unpickler(f)
        while True:
            try:
                loaded_data = unpickler.load()
            except Exception:
                break
            print("loaded:", loaded_data)
    

    然而,在我看来,依赖异常处理来实现这一点似乎是一种廉价的黑客行为。这是一个好方法还是有更好的方法?如果我想提前知道所需的调用数,我应该在文件的开头显式地保存它吗?

    2 回复  |  直到 8 年前
        1
  •  1
  •   martineau    8 年前

    正如@MartijnPieters所说,你目前的方法没有什么错。如果您想使实际获取数据的代码更具可读性(即更简洁和“更干净”),可以创建 generator 隐藏丑陋细节的函数:

    import pickle
    
    def unpickled_items(filename):
        """ Unpickle a file of pickled data. """
        with open(filename, "rb") as f:
            while True:
                try:
                    yield pickle.load(f)
                except EOFError:
                    break
    
    # Create test file.
    with open("data.pk", "wb") as f:
        pickler = pickle.Pickler(f)
        pickler.dump("message1")
        pickler.dump("message2")
        pickler.dump("message3")
    
    
    loaded_data = [item for item in unpickled_items("data.pk")]
    print("saved data:", loaded_data)
    
        2
  •  1
  •   Martijn Pieters    8 年前

    这是一个很好的方法;您只需读取文件存储的所有pickle。

    另一种方法是首先将对象计数写入文件:

    with open("data.pk", "wb") as f:
        f.write((3).to_bytes(2, 'big'))  # 2 bytes gives you enough room for expansion
        pickler = pickle.Pickler(f)
        pickler.dump("message1")
        pickler.dump("message2")
        pickler.dump("message3")
    
    with open("data.pk", "rb") as f:
        count = int.from_bytes(f.read(2), 'big')
        unpickler = pickle.Unpickler(f)
        for i in range(count):
            loaded_data = unpickler.load()
            print("loaded:", loaded_data)