【问题标题】:How to clone a class but not copy mutable attributes?如何克隆一个类但不复制可变属性?
【发布时间】:2020-05-24 17:24:58
【问题描述】:

我正在尝试编写能够跟踪创建的类实例并通过会话保存它的 python 代码。我试图通过在类减速中创建一个列表来跟踪实例。我的代码如下:

class test_object:
    _tracking = []

    def __init__(self, text):
        self.name = text
        test_object._tracking.insert(0, self)

with open("tst.pkl", mode="rb") as f:
    try:
        pickles = dill.load(f)
    except:
        pickles = test_object
        logger.warning("Found dill to be empty")
f.close()

当腌制数据为空时,我的问题是处理。在这种情况下,我想做的是简单地使用基类。我遇到的问题是test_object._tracking 最终等于pickles._tracking。有没有办法复制test_object,这样当test_object._tracking 获得更新时,pickles._tracking 保持不变?

【问题讨论】:

  • 在 'except' 部分,您将泡菜设置为 test_object 类,而不是该类的实例。是这个意图吗?为什么? (另外,不需要关闭 f,因为您使用的是 'with')。
  • @Roy2012 是的,关键是将它设置为类。我想腌制这个类,它有一个实例列表。这个想法是以简单而紧凑的方式将类及其实例腌制和解封。这里的想法是,如果没有任何东西被腌制,我想要一种在没有任何实例的情况下复制类的方法。由于test_object还没有被调用,它的_tracking应该是空的,所以这是一种在没有任何实例的情况下将pickle设置为类的方法。

标签: python class oop dill


【解决方案1】:

您可以执行以下操作:

import dill 

class test_object:
    _tracking = []

    def __init__(self, text):
        self.name = text
        test_object._tracking.insert(0, self)

test_1 = test_object("abc")
print(test_object._tracking)
# result: [<__main__.test_object object at 0x11a8cda50>]

with open("./my_file.txt", mode="rb") as f:
    try:
        pickles = dill.load(f)
    except:
        pickles = type('test_object_copy', test_object.__bases__, dict(test_object.__dict__))
        pickles._tracking = []

        print("Found dill to be empty")
# The above results in "Found dill to be empty"

print(pickles._tracking)
# prints []

它会将泡菜设置为原始类的副本。然后它的跟踪属性将为空,并且与原始的“跟踪”不同。

【讨论】:

  • 这不能按预期工作。我通过在except 子句中添加test_object._tracking.append("test"); print(pickles._tracking) 来测试它,并得到['test'] 的输出。 IE。这种方法的问题是pickletest_object 共享一个_tracking 列表。
  • 知道了。我认为您想确保 pickle 对象在创建后不会随类更改。我将更改代码以确保 _tracking 在创建时为空。
  • 它确实有效,但它有点 hacky。我想知道是否有更通用的解决方案。我担心的是我是否需要我的班级来跟踪更多的事情,尽管我认为这对于一个如此晦涩的问题来说已经足够了,
  • 是的......这有点 hacky - 但是等到你看到我的另一个解决方案,它结合了组装、COBOL 和一些鸭带:)
猜你喜欢
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
  • 2011-04-15
相关资源
最近更新 更多