在运行时重置/重新加载嵌套类的类属性

时间:2019-03-15 13:14:42

标签: python python-3.x class oop nested

我在Python 3中使用嵌套类来实现“簿记”目的。类结构(高度简化)看起来像这样:

class BookKeeping:

    class ItemA:
        count = 0
        item_list = []

        @classmethod
        def add(cls, item_a):
            cls.count += 1
            cls.item_list.append(item_a)

    class ItemB:
        count = 0
        item_dict = {}

        ...

通过此类,可以方便地跟踪和访问我正在建模的系统的某些“全局”属性。具有嵌套的类允许清晰的命名空间。例如,在任何模块中,我都可以... import BookKeeping as BK并检查有多少ItemB个对象(BK.ItemB.count)。

在程序的某个时刻,我想“重置”所有类属性,即,我想再次将BookKeeping.ItemA.count设置为0,并清空列表和字典等。

很显然,我可以添加诸如BookKeeping.reset()之类的顶级类方法,该方法可以“手动”重置所有值,例如:

class BookKeeping:

    @classmethod
    def reset(cls):
        cls.ItemA.count = 0
        cls.ItemA.item_list = []
        cls.ItemB.count = 0

        ...

但是,这对我来说似乎是容易出错的方法,它涉及到该类的“维护”(我可能会忘记重置一些属性)。请注意,我的真实课堂比我提供的示例还要复杂。

在运行时将所有类属性重置为其原始状态的最简单方法是什么?

1 个答案:

答案 0 :(得分:2)

因此,预先:您实际上应该这样做吗?可能不是。

实际上,我建议您尝试重新考虑您的项目结构,因为通常应避免使用全局状态。

如果您仍然想那样做...

当心,一些未经测试的(!)奥术魔法即将出现:

import copy

class BookKeeping(object):
    __backup = {}

    class ItemA(object):
        ...

    class ItemB(object):
        ...

    @classmethod
    def reset(cls):
        for name, backup in cls.__backup.items():
            inner_cls = getattr(cls, name)
            for k, v in backup.items():
                setattr(inner_cls, k, copy.deepcopy(v))

for i in dir(BookKeeping):
    if not i.startswith("_"):
        obj = getattr(BookKeeping, i)
        BookKeeping.__backup[i] = {k: copy.deepcopy(getattr(obj, k)) for k in dir(obj)}

其他说明:这通常是一个棘手的问题。但是,您也可以对其他嵌套结构使用相同的技术,并以不同的方式处理类型,而不是以不同的方式处理第一层。

这是一个问题,因为您不想deepcopy类型本身,因为那样会在当时所有活动对象以及所有新对象以及当前新的全局状态之间复制状态。