【问题标题】:create dynamic linked variables创建动态链接变量
【发布时间】:2020-07-16 23:33:38
【问题描述】:

是否可以创建动态链接变量?这样original_VAR 中的更改将自动在copied_VAR 中生效?像这样:

original_VAR = 'original_VAL'
copied_VAR = original_VAR

original_VAR = 'modified_VAL'

print(copied_VAR)
#desired output:
>>>> 'modified_VAL'

在少数情况下可以为列表创建类似的行为:

original_DICT_ARR = [{'key': 'original_VAL'}]


# 1 - does not create a dynamic link
copied_DICT_ARR = [value for value in original_DICT_ARR]

# 2 - does create a dynamic link
copied_DICT_ARR = original_DICT_ARR

# 3 - does create a dynamic link, if the copied element is a list or dict, but not if string, boolean, int, float
copied_DICT_ARR = []
copied_DICT_ARR.append(original_DICT_ARR[0])

# MODIFICATION:
original_DICT_ARR[0]['key'] = 'modified_VAL'

# RESULT for 2,3
print(copied_DICT_ARR[0])

>>>> {'key': 'modified_VAL'}

我为什么要这样做?

我正在构建一个列表,列表中充满了 dict 对象。我需要为某个 dict 键赋值。

稍后,该值可能会改变 - 我不想再次遍历列表中的所有字典。我想更改原始变量,并自动在所有字典中生效。

【问题讨论】:

  • 不,没有办法做到这一点。当然,您可以使用不同的变量引用同一个 object,然后 mutate 该对象,这些更改将被反映,但您不能链接两个变量,其中 re - 分配一个变量会自动重新分配另一个变量
  • 您误解了您的示例,没有“动态链接”。在某些情况下,您只是引用同一个对象,例如copied_DICT_ARR = original_DICT_ARR。这不会复制。当然,当您改变该对象时,对该对象的任何引用都会看到该突变。 intstrboolfloattuple 对象是不可变的,它们不公开 mutator 方法。你真的需要阅读:nedbatchelder.com/text/names.html
  • 简单的解决方案是用一些可变对象填充您的字典。简单地说,class Value: def __init__(self, value): self.value = value,然后,value = Value(0),用value 创建你的字典列表,然后你可以做value.value = 99

标签: python variables dynamic


【解决方案1】:

您可以保留以后要修改的特定dict 的引用。由于它指的是相同的基础字典 - 更改将反映在您的参考中。像这样:

original_DICT_ARR = [{'key': 'original_VAL'}, {'key': 'another_val'}]

target_dict = original_DICT_ARR[0]

# MODIFICATION:
original_DICT_ARR[0]['key'] = 'modified_VAL'

# RESULT for 2,3
print(target_dict)

给予:

{'key': 'modified_VAL'}

【讨论】:

    【解决方案2】:

    您可以通过使用可变对象和子类UserDict 并覆盖__getitem__ 来实现这一点并保持抽象:

    class ChangingVal:
    def __init__(self, val):
        self.val = val
    
    class ChangingValsDict(UserDict):
        def __getitem__(self, key):
            ret = self.data[key]
            if isinstance(ret, ChangingVal):
                ret = ret.val
            return ret
    
    my_dict = ChangingValsDict()
    
    changing_val = ChangingVal(3) 
    my_dict["changing_value"] = changing_val
    
    print(my_dict["changing_value"]) # -- outputs "3"
    
    # change your value
    changing_val.val = 6
    
    print(my_dict["changing_value"]) # -- outputs "6"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 1970-01-01
      • 2011-10-16
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多