Python 迷惑系列 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
damngoto
V2EX    Python

Python 迷惑系列

  •  
  •   damngoto 2022-07-29 11:06:14 +08:00 4844 次点击
    这是一个创建于 1174 天前的主题,其中的信息可能已经有所发展或是发生改变。
    class CSStudent: stream = 'cse' a = CSStudent() a.stream = 'ece' b = CSStudent() CSStudent.stream = 'mech' c = CSStudent() print(a.stream) # ece print(b.stream) # mech print(c.stream) # mech 

    直觉上看的话 a 应该也要被改才对,不知道 py 的机制。 id 看的话 id(a.stream) 的地址确实与 bc 不一样,所以没有受到影响。

    23 条回复    2022-08-02 16:48:53 +08:00
    BeautifulSoup
        1
    BeautifulSoup  
       2022-07-29 11:17:59 +08:00
    应该是类实例和类对象的问题,a.stream = 'ece'修改的是类实例,CSStudent.stream = 'mech'修改的是类对象。
    a.stream = 'ece'是在对象内部新建的实例变量(可以理解为 self.stream),会“覆盖”类内全局变量 stream ;而 bc 那打印就是取的类内全局变量 stream
    如果真的做项目不要这么写,十分不规范
    lyang
        2
    lyang  
       2022-07-29 11:19:07 +08:00
    https://m.py.cn/jishu/jichu/32471.html
    创建实例时,类属性不会成为实例属性。当为它们分配值时,它们成为实例属性。
    codeMore
        3
    codeMore  
       2022-07-29 11:21:40 +08:00
    CSStudent.tream 是类变量,改变类变量,所有的实例都会受到影响。
    a.stream 为什么没有受到影响,是因为 a.stream 其实算是新建的实例变量 stream 了,已经不是类变量的 stream 了。参考文章:http://c.biancheng.net/view/2283.html
    krixaar
        5
    krixaar  
       2022-07-29 11:22:34 +08:00   3
    https://docs.python.org/zh-cn/3/tutorial/classes.html#random-remarks
    > 如果同样的属性名称同时出现在实例和类中,则属性查找会优先选择实例
    所以 b 和 c 的 实例 没有 stream ,就找了 类 的 stream ,而 a 的实例有 stream ,所以直接用实例的 stream 。
    damngoto
        6
    damngoto  
    OP
       2022-07-29 11:34:43 +08:00
    这个网站看起来不错,学习学习。
    damngoto
        7
    damngoto  
    OP
       2022-07-29 11:35:00 +08:00
    filwaline
        8
    filwaline  
       2022-07-29 12:12:10 +08:00   1
    https://github.com/satwikkansal/wtfpython#-class-attributes-and-instance-attributes

    其实在 wtf-python 里就有写,你肯定没看(滑稽
    RockShake
        9
    RockShake  
       2022-07-29 12:18:00 +08:00
    Python Tutor 可视化很直观
    ruanimal
        10
    ruanimal  
       2022-07-29 14:10:55 +08:00
    学一门语言,还是需要认真看看语法的。。
    killva4624
        11
    killva4624  
       2022-07-29 14:14:13 +08:00
    类属性一般都不改吧,太不可控了,很难去评估有些哪些对象会收到影响。
    damngoto
        12
    damngoto  
    OP
       2022-07-29 14:27:46 +08:00
    @filwaline 老哥又来了,一上来就练葵花宝典不好吧。
    damngoto
        13
    damngoto  
    OP
       2022-07-29 14:53:15 +08:00
    @ruanimal 你说的是官网吗?
    filwaline
        14
    filwaline  
       2022-07-29 15:35:38 +08:00 via Android
    @damngoto 这怎么就葵花宝典了哈哈哈,先浏览几遍,对 Python 有什么坑留点印象,以后遇到问题了好快速解决,而不是一头雾水
    damngoto
        15
    damngoto  
    OP
       2022-07-29 15:58:27 +08:00
    @filwaline 你说的有道理,但是不太适合我。我就是心血来潮看一下,一年写不了几行代码。
    AV1
        16
    AV1  
       2022-07-29 17:17:16 +08:00
    python 的 class 设计缺陷,定义时没有区分静态成员和实例成员。
    a.stream 被修改之前指向静态成员,修改之后就变成实例成员了。
    JS 的 class 吸取了这个教训,增加 static 修饰符,而且不允许通过实例直接访问静态成员。
    Richard14
        17
    Richard14  
       2022-07-29 17:30:21 +08:00   1
    @DOLLOR 实例未定义向方法引用,语言特性到你这说成语言缺陷了,js 的 class 可大哥别笑二哥了

    @damngoto 有没有一种可能,怪的是 OP ,向上替换的特性不了解,然后还一定要用类属性,这又不是连函数和变量都没有的 java ,python 这有很多神奇的东西,比如全局变量。所以 OP 要借助类属性实现什么设计?
    damngoto
        18
    damngoto  
    OP
       2022-07-29 18:09:19 +08:00
    @Richard14 网上随手看到的一个例子:)
    AV1
        19
    AV1  
       2022-07-29 21:06:07 +08:00 via Android
    @Richard14
    嗯,不是“缺陷”,是缺点。说明 Python 当初设计欠缺考虑,出现了不同于其他语言的反直觉现象了。这个问题我都在 v2 上遇到几次了。
    JS 的以前的原型写法也会遇到类似 Python 这个问题,但 class 就没这个问题了,不会出现静态成员和实例成员混淆的现象,这方面更符合其他主流语言的思维。在这一点还是可以笑话一下 Python 的。
    ipwx
        20
    ipwx  
       2022-07-29 21:53:47 +08:00
    @damngoto 你把类属性理解成对象属性的默认值就行。
    documentzhangx66
        21
    documentzhangx66  
       2022-07-30 05:08:45 +08:00   1
    无论结论是什么,谁这样写代码,就开除谁。

    这特么团队毒瘤吧。
    solopython
        22
    solopython  
       2022-07-30 23:36:08 +08:00
    最佳实践是使用类名来更改类变量的值。因为如果我们尝试通过使用一个对象来更改类变量的值,则会为该特定对象创建一个新的实例变量,它会隐藏类变量。
    fgwmlhdkkkw
        23
    fgwmlhdkkkw  
       2022-08-02 16:48:53 +08:00
    你就不能怀疑你自己的直觉吗?……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5792 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 01:50 PVG 09:50 LAX 18:50 JFK 21:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86