首页 文章

Python 3.x中动态视图对象的范围

提问于
浏览
3

原始对象被删除后,python中的视图对象会发生什么?例如,

a = {'foo': 1 , 'bar': 2, 'baz': 3 }
b = a.keys()   # => dict_keys(['bar', 'foo', 'baz'])

此时,如果对字典进行了任何更改,它们将反映在b中 . 例如,

a['qux'] = 4
print(b)  # => dict_keys(['bar', 'qux', 'foo', 'baz'])

但是,删除字典时,动态变量仍包含已删除字典中键的所有值 .

del a
a        # NameError: name 'a' is not defined
print(b) # => dict_keys(['bar', 'qux', 'foo', 'baz'])

Question

从本质上讲,我想知道是否必须 always 确保即使在删除字典后也删除了具有键值的任何变量 . 如果字典很大,这可能是内存泄漏的潜在原因吗?任何反馈将不胜感激 .

Side Note:

而且,是的,我知道我可以将密钥放在列表中:

c = list(a.keys())

但我使用的是视图对象,因为与list相比,它们的内存占用量更小 .

2 回答

  • 0

    我建议不要使用术语变量 . 更好地使用允许访问对象的名称 . 对于您的示例 ab 是对象字典的名称和字典的键 . 在Python 3中, dict.keys() 为您提供了一个键视图对象,它反映了基础字典中的更改 . 因此,键视图对象保持对字典的引用 .

    所以你不要删除字典,而是删除指向它的名称 . 只有当没有更多名称(对字典的引用)时,垃圾收集器才会删除字典 .

    如果使用不能在全局对象上运行的函数以结构化方式编程,则内存泄漏相当罕见 . 在实践中,通常会谨慎使用 del .

  • 3

    del 只会减少python底座中对象的引用计数器 . 当程序中没有活动的引用时,字典本身将在很久以后从内存中释放(处置) .

    keys() product保存在变量中时,会增加dict 's reference counter, additionaly to dict' s变量本身 . 当任何引用留给它时,变量不会被释放 .

    我可以用非常简单但绝对相同的结构来表达你的代码:

    a = dict()
    b = a # reference only
    del(b)
    # dict is not garbage-collected, as a still holds the reference
    
    a != None # True
    

相关问题