你们说 Python 这个是 Bug 还是 Feature?

2022-08-30 15:44:32 +08:00
 lanlanye
class Foo:
    def __init__(self, s: set = set()):
        self.s = s


if __name__ == "__main__":
    f1 = Foo()
    f2 = Foo()
    f1.s.add(1)
    f1.s.add(2)
    f1.s.add(3)
    print(f2.s)

版本 3.10.4

结果会是什么呢?

7119 次点击
所在节点    Python
71 条回复
est
2022-08-30 17:48:44 +08:00
@Aloento 怎么说呢,面对技术选型,比如用 java 的倒霉的多了去了。但是人数多,你不怎么看得出来,倒霉了只能算你自己蠢。。。。。
Vegetable
2022-08-30 18:01:02 +08:00
gengchun
2022-08-30 18:23:57 +08:00
这个算是 101 的东西吧。这个是 mutable defaults 另一个是 closures late binding 。

这两个有没有放在最前面介绍应该做为判断教材是否合格的主要指标。

另外评价别人的代码,这也是很重要的参考,一旦出现,就要认真想一想了。
x7DnVcd9bA706oWp
2022-08-30 18:30:05 +08:00
@kkhaike 是的,一般这么写
class Foo:
def __init__(self, s=None):
if s is None:
s = set()
self.s = s
DOLLOR
2022-08-30 18:30:47 +08:00
老实承认,就是设计失误。

其他语言的默认参数的表达式在调用的时候才执行的,但 python 是在定义的时候执行的。前者更符合多数人的直觉。
x7DnVcd9bA706oWp
2022-08-30 18:31:17 +08:00
@Aloento 菜还怪人家语言不行
Vegetable
2022-08-30 18:35:47 +08:00
@duange7X24 一般是 self.s = s or set()
lucays
2022-08-30 18:48:13 +08:00
目前应该所有 py 教学都会说避免这个,要说他是 feature 肯定不是,你根本不可能在任何场景用这个
说是 bug 嘛,这个好像也不太要修复,硬要 2 选 1 那就是 bug

还有一个就是,python 的 for 循环完了可以直接接 else 没有 if ,是 feature ,显然不是 bug ,但是我觉得,也应该删除这个 feature ,纯纯的屁用没有,如果真有人用了,还得反应一会才知道这段代码在干嘛,也很反直觉
acmore
2022-08-30 18:50:14 +08:00
是 Feature ,但它会导致一大堆 Bug
所以是个坏 Feature
Aloento
2022-08-30 21:48:34 +08:00
@est 中肯的,客观的


@duange7X24 确实,我推荐您使用 Jvav
westoy
2022-08-30 22:03:28 +08:00
python 默认的 args 在__defaults__下面, 不可能让__defaults__的结果随缘吧?

本质还是可变和不可变对象引用的问题啊,js 虽然能规避掉 (args=[])这种问题, 但是要是下意识写出 const func = (args=window.xxxx)=>{}不一样么
jatsz
2022-08-30 23:21:34 +08:00
测试的阶段算 Bug ,这种 Public API 都 release 的就算 Feature 了,只能将错就错,外加补一下文档了。
FreeEx
2022-08-31 00:49:42 +08:00
学习了,以前好像写过这样的代码…
dayeye2006199
2022-08-31 00:56:54 +08:00
老 feature 了
mikewang
2022-08-31 02:25:29 +08:00
@Vegetable Python 之父中国分父是吧
js8510
2022-08-31 07:42:10 +08:00
lanlanye
2022-08-31 09:24:04 +08:00
@westoy 确实,其实发现这个现象后很快就反应过来原因了,但直觉上还是觉得参数列表里的东西应该是表达式而不是直接求好的值……
lanlanye
2022-08-31 09:26:16 +08:00
@Vegetable 老实说我 16 年入门时看过,当时好像还没有这段……不过我也记不太清了
fbichijing
2022-08-31 10:26:07 +08:00
很多 Python 书函数部分都会提到,**参数尽量不要用可变对象**。函数参数部分的可变对象在内存中使用了相同的地址,导致实例化后的操作会产生意料之外的行为。

我觉得说是 bug 有点过,至少是可以理解的行为。只是在一开始不知道的时候容易被坑。

```python
class Foo:
def __init__(self, s=None):
self.s = s if s else set()
```
wtfedc
2022-08-31 10:28:06 +08:00
@zone10 结构体默认可不是 nil

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

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

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

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

© 2021 V2EX