首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >python类属性引用副作用?

python类属性引用副作用?
EN

Stack Overflow用户
提问于 2020-09-01 13:59:23
回答 1查看 30关注 0票数 0

我被代码中的一个bug弄糊涂了:

使用distribute_tags方法给出下面的类

代码语言:javascript
运行
复制
class ConsulData:
    def __init__(self, logger, marshalled_data, prom_numbering, prom_count):
        self.logger = logger
        self.current = marshalled_data
        self.to_update= {}
        self.payloads = []
        self.prom_count = prom_count
        self.prom_numbering = prom_numbering

    def distribute_tags(self):
        cpt = 0
        cp_current = copy.deepcopy(self.current)
        for keys, values in cp_current.items():
            num = (cpt % self.prom_count) + self.prom_numbering
            prometheus_tag = "prometheus-{}".format(num)
            if not prometheus_tag in values['Tags']:
                self.to_update[keys] = values
                data = []
                [data.append(v) for v in values['Tags'] if not v.startswith("prometheus")]
                data.append(prometheus_tag)
                self.to_update[keys]['Tags'] = data
            cpt += 1
    {...}

如果没有深度复制,则在循环执行之后,print(self.current == self.to_update)返回True

print(id(self.current) == id(self.to_update))返回False。

deepcopy的使用修复了我意想不到的bug,因为在distribute_tags内部所做的工作或多或少与执行的相同:

代码语言:javascript
运行
复制
In [2]: d1 = {'key1':'value1', 'key2':'value2'}
In [3]: d2 = {}

In [4]: for k, v in d1.items():
   ...:     d2[k] = v

In [6]: d2['key1'] = 'lol'

In [8]: d1
Out[8]: {'key1': 'value1', 'key2': 'value2'}

In [9]: d2
Out[9]: {'key1': 'lol', 'key2': 'value2'}

其中,d1数据不受对d2的修改的影响,因为它们是对不同对象的两个不同的引用。

传递给init函数的如下所示:

代码语言:javascript
运行
复制
payload = {
    'service1': {
        'ID': 'service1',
        'Service': 'service1', 
        'Tags': ['sre-metrics', 'prometheus-2'], 
        'Meta': {
            'env': 'dev', 
            'namespace': 'test', 
            'path': '/path1', 
            'svc': 'svc1', 
            'team': 'testing'},
        'Port': 80, 
        'Address': 'test1.testing.org', 
        'Weights': {'Passing': 1, 'Warning': 1}, 
        'EnableTagOverride': False
    }, 
...
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-01 14:18:38

如果你不做个深拷贝,

代码语言:javascript
运行
复制
self.to_update[keys] = values

为同一个values字典指定一个引用。当你晚些时候

代码语言:javascript
运行
复制
self.to_update[keys]['Tags'] = data

你在修改那个字典,所以这两个值仍然相等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63689220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档