今天不小心踩了可变类型的坑

2019-02-21 14:50:49 +08:00
 Vegetable
class Example:
    
    # 坑
    container = {}
    
    def __init__(self):
        # do init
        pass
    def result(self):
        if self.container:
            return self.container()
        self.container["a"] = self._a()
        self.container["b"] = self._b()
        return self.container
    def _a(self):
        # fetch data
        return "a"
    
    def _b(self):
        # fetch data
        return "b"
    

今天用了一个这样的结构来处理部分数据.然后就出现了第二个实例返回的结果和上一个一样的情况. 反思了一下自己在写代码的时候根本没注意到这个 container 在两个实例里可能会指向同一个地址的问题.写 python 两年多一直在很小心 list 和 dict 作为参数时避免采坑,没想到今天换了个地方踩了一下,不知道别人是不是了解这个坑,发出来给大家看看吧

3140 次点击
所在节点    Python
20 条回复
j0hnj
2019-02-21 15:05:58 +08:00
这...是常识吧,楼主写两年多 Python 写的都是啥?
freakxx
2019-02-21 15:08:14 +08:00
静态变量

不过确实有很大部分直接入 python 并不了解这个东西。
whoami9894
2019-02-21 15:10:03 +08:00
因为类变量是实例共享的,不可变类型修改时会修改实例变量,可变类型就是这种情况

return self.container() 这里多了对括号
araraloren
2019-02-21 15:13:36 +08:00
可变类型? 静态变量?
9hills
2019-02-21 15:14:58 +08:00
尽量避免使用类变量,使用大写定义常量,只读不写。

类变量也有并发冲突问题。
liu19931020
2019-02-21 16:47:04 +08:00
lolizeppelin
2019-02-21 16:57:35 +08:00
....两年真白写了

我估计单例你都没写过......
Orenoid
2019-02-21 17:03:32 +08:00
@liu19931020 请问这是什么书
windfarer
2019-02-21 17:06:16 +08:00
我在刚入行半年的时候,就修过之前老哥留下的这样的 bug= =
leoli
2019-02-21 17:17:20 +08:00
这也不是楼主所说的 "可变类型的坑" 吧。这都能理解错,楼主还是要严谨点。
liu19931020
2019-02-21 17:18:26 +08:00
@Orenoid Python 基础教程(第三版)
zwzmzd
2019-02-21 17:20:07 +08:00
你需要的是把 self.container 变量定义在__init__函数中,和可变类型没关系
cyspy
2019-02-21 17:28:06 +08:00
兄弟估计没学过 cpp 或者 java,面向对象底子不够
huahuajun9527
2019-02-21 17:34:45 +08:00
这应该怪 类属性 跟 实例属性 没搞懂
xpresslink
2019-02-21 17:45:19 +08:00
按理说两年了不应该还踩这个坑啊。再说了这个也不 可变类型的坑,
明显就是类变量和实例变量的概念和区别没弄明白。

你这个需求下创建实例变量应该把放到 init 方法中。
class Example:

◇◇◇◇def __init__(self):
◇◇◇◇◇◇◇◇# do init
◇◇◇◇◇◇◇◇self.container = {}
◇◇◇◇◇◇◇◇pass
freakxx
2019-02-21 17:51:45 +08:00
我觉得某楼也不必这么说楼主,

这个东西,就是点与面的问题,没必要把话说绝。
zst
2019-02-21 17:55:34 +08:00
老实说 Python 这个确实是个坑.......不知道设计的时候咋想的,所以一般丢到 init 里面去比较好
wangxiaoaer
2019-02-21 17:58:18 +08:00
我 Python 不熟,但这个跟可变类型有啥关系啊?看起来是成员变量跟静态变量的问题。
shm7
2019-02-21 19:22:37 +08:00
lz 从 java 来的吧; python 里面用 a, b = a(), b() 不需要写什么 pojo
shm7
2019-02-21 19:24:47 +08:00
的确和可变类型没啥关系,恐怕 java 也没写好,静态的 class 的属性和 obj 的属性用法都是一致的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/537265

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX