遍历Python对象树

遍历Python对象树,python,reload,traversal,Python,Reload,Traversal,我试图在Python中实现动态重载对象,以实时反映代码更改 重新加载模块是可行的,但我必须重新创建模块类的每个实例,以使更改生效 问题是对象数据(对象\uuuuuu dict\uuuuu内容)在该过程中丢失 所以我尝试了另一种方法: def refresh(obj, memo=None): if memo is None: memo = {} d = id(obj) if d in memo: return memo[d] = No

我试图在Python中实现动态重载对象,以实时反映代码更改

重新加载模块是可行的,但我必须重新创建模块类的每个实例,以使更改生效

问题是对象数据(对象
\uuuuuu dict\uuuuu
内容)在该过程中丢失

所以我尝试了另一种方法:

def refresh(obj, memo=None):
    if memo is None:
        memo = {}
    d = id(obj)
    if d in memo:
        return
    memo[d] = None
    try:
        obj.__class__ = getattr(sys.modules[obj.__class__.__module__], 
                obj.__class__.__name__)
    except TypeError:
        return
    for item in obj.__dict__.itervalues():
        if isinstance(item, dict):
            for k, v in item.iteritems():
                refresh(k, memo)
                refresh(v, memo)
        elif isinstance(item, (list, tuple)):
            for v in item:
                refresh(v, memo)
        else:
            refresh(item, memo)
令人惊讶的是,它的工作!对我的对象调用refresh()后,新代码将生效,而无需重新创建它们


但我不确定这是不是穿越物体的正确方法?有没有更好的方法来遍历对象的组件?

请参阅Python Cookbook(或者更好的版本是“打印”版本,我相信您可以通过google book search免费阅读,或者在O'Reilly的“Safari”上阅读网站使用免费1周试用订阅——我对哈德逊的原始配方做了大量编辑,以获得“印刷本”版本!)。

请参见Python烹饪书(或者更好的是,它的“印刷本”版本,我相信你可以通过谷歌图书搜索免费阅读,或者在O'Reilly的“Safari”上阅读使用免费1周试用订阅的站点——我对Hudson的原始配方进行了大量编辑以获得“印刷书籍”版本!)。

这与我采用的解决方案非常相似(一些“顶级”类被包装并跟踪其实例以允许重新加载它们)。问题是,我不想包装包中的所有类(或者像您的示例中那样从重新加载的类继承),只想包装顶级类。这就是为什么我需要一个对象树遍历函数的原因。我相信你不能完全通用地做到这一点——根据插槽和其他元类功能的不同,Python对象可能被编码为根本不支持这一点(这就是为什么在编写扩展代码时,需要为垃圾收集遍历、weakrefs、pickling/unpickling和c提供特定支持的原因)。打开文件、DB连接、生成器对象、锁等。如果您愿意冒丢失某些部分的风险,请确保至少覆盖集合、DEQUE、defaultdicts的默认\u工厂成员等。好的,那么我只需在我的迭代开关中添加更多类型测试。如果有某种has\u序列\u接口/has\u映射\u接口,那就太好了()函数来测试对象的迭代方式。这与我采用的解决方案非常相似(一些“顶级”类被包装并跟踪它们的实例以允许重新加载它们)。问题是我不想包装包中的所有类(或从重新加载的类继承,如您的示例所示),只是顶级的。这就是为什么我需要一个对象树遍历函数。我相信你不能用完全的通用性来完成它——根据插槽和其他元类功能,Python对象可能被编码为根本不支持它(这就是为什么在编写扩展代码时,需要为垃圾收集遍历、weakrefs、pickling/unpickling和c提供特定支持的原因)。打开文件、DB连接、生成器对象、锁等。如果您愿意冒丢失某些部分的风险,请确保至少覆盖集合、DEQUE、defaultdicts的默认\u工厂成员等。好的,那么我只需在我的迭代开关中添加更多类型测试。如果有某种has\u序列\u接口/has\u映射\u接口,那就太好了()函数用于测试对象的迭代方式。