【问题标题】:How can I make my namedtuple actually immutable?我怎样才能让我的 namedtuple 实际上是不可变的?
【发布时间】:2014-07-10 03:18:44
【问题描述】:

我创建了一个 SETTINGS 对象作为namedtuple,认为其中包含的列表是不可变的。我错了,因为在整个链中,只使用了对完全可变字典中原始列表的引用。

因此,当我在我的列表中调用 .pop() 时,它也会将其从我认为的非不变的 namedtuple 中删除。现在我在#python 一段时间后明白了为什么这一切都会发生。

我想知道的是:如何创建 SETTINGS namedtuple 作为行尾? 只是数据,不引用任何其他对象,在一个很好的用户中-可编辑的方式?我觉得dict 是人类最容易读取/编辑的数据结构,因此我将dict 解压缩到namedtuple

>>> from collections import namedtuple
>>>
>>> _settings = {
...     'ROOM_NAMES': [
...         'Master Bedroom',
...         'Bath',
...         'Kitchen',
...         'Study',
...     ],
... }
>>> _Settings = namedtuple('_Settings', [k for k in _settings.keys()])
>>> SETTINGS = _Settings(**_settings)
>>>
>>> names = SETTINGS.ROOM_NAMES
>>> names
['Master Bedroom', 'Bath', 'Kitchen', 'Study']
>>> type(names)
<class 'list'>
>>> # POP 'Study' OFF OF THE LIST
>>> name = names.pop() 
>>>
>>> # THIS IS WHAT I EXPECT              
>>> name in names                    
False
>>>
>>> # MISSING HERE AS THIS IS THE END OF THE LINE
>>> name in _settings['ROOM_NAMES']  
False
>>>
>>> # MISSING HERE FROM MY NAMEDTUPLE IN THE MIDDLE OF THE LINE
>>> name in SETTINGS.ROOM_NAMES      
False
>>>

【问题讨论】:

    标签: python pass-by-reference immutability python-3.4 namedtuple


    【解决方案1】:

    我认为您对元组的实际工作方式感到困惑。即使是“真实的”元组也不会使包含的对象不可变,只是元组本身:

    >>> x  = [1,2,3]
    >>> t = (x,0,3)
    >>> t[0].append(4)
    >>> t
    ([1, 2, 3, 4], 0, 3)
    

    我猜你想做的是.copy()列表,然后再开始变异。

    >>> a = x.copy()
    >>> t = (a,0,1)
    >>> t[0].append(5)
    >>> t
    ([1, 2, 3, 4, 5], 0, 1)
    >>> x
    [1, 2, 3, 4]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      相关资源
      最近更新 更多