V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
itskingname
V2EX  ›  推广

在 Python 中, a += b 并不总是等价于 a = a + b

  •  
  •   itskingname · 2019-01-29 21:27:43 +08:00 · 3830 次点击
    这是一个创建于 2154 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家经常在一些博客中看到这样的说法:

    a += 1
    

    等价于

    a = a + 1
    

    这种说法实际上并不准确。

    我们来看一个例子:

    >>> a = [1, 2, 3]
    >>> a += (4,)
    >>> a
    [1, 2, 3, 4]
    
    >>> a = [1, 2, 3]
    >>> a = a + (4,)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can only concatenate list (not "tuple") to list
    

    这里报错了,说明a += ba = a + b并不是完全等价的。

    请点击查看完整内容:在 Python 中,a += b 并不总是等价于 a = a + b

    misaka19000
        1
    misaka19000  
       2019-01-29 21:44:35 +08:00 via Android
    不错,学习了
    OysterQAQ
        2
    OysterQAQ  
       2019-01-29 21:53:39 +08:00 via iPhone
    学习了,查了下,在 java 中从本质讲这两者确实是两码事
    sdijeenx
        3
    sdijeenx  
       2019-01-29 22:22:07 +08:00   ❤️ 2
    是这样的。

    These methods are called to implement the augmented arithmetic assignments (+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self). If a specific method is not defined, the augmented assignment falls back to the normal methods. For instance, if x is an instance of a class with an __iadd__() method, x += y is equivalent to x = x.__iadd__(y) . Otherwise, x.__add__(y) and y.__radd__(x) are considered, as with the evaluation of x + y. In certain situations, augmented assignment can result in unexpected errors (see Why does a_tuple[i] += [‘ item ’] raise an exception when the addition works?), but this behavior is in fact part of the data model.
    https://docs.python.org/3/reference/datamodel.html


    Why does a_tuple[i] += [‘ item ’] raise an exception when the addition works?
    This is because of a combination of the fact that augmented assignment operators are assignment operators, and the difference between mutable and immutable objects in Python.

    This discussion applies in general when augmented assignment operators are applied to elements of a tuple that point to mutable objects, but we ’ ll use a list and += as our exemplar.
    https://docs.python.org/3/faq/programming.html#faq-augmented-assignment-tuple-error
    rekulas
        4
    rekulas  
       2019-01-29 22:46:10 +08:00
    这个,我觉得别人说的是数值吧,你这个改成了 dict 相加不符合别人的原意了?(非 python 研究者,这似乎是 dict 吧)
    bumz
        5
    bumz  
       2019-01-29 22:57:10 +08:00
    本来就不是一回事

    只不过对于值语义的类型,这二者的结果期望是等价的

    list 是引用语义的类型,不等价
    whwq2012
        6
    whwq2012  
       2019-01-29 22:57:59 +08:00 via Android
    偷换概念。。一般说的+=是数字运算,又不是其他对象。。
    helloworld000
        7
    helloworld000  
       2019-01-29 23:29:32 +08:00   ❤️ 12
    现在从 python 开始学编程的人都已经不知道 数据类型这么个东西了吗。。。。
    mario85
        8
    mario85  
       2019-01-30 00:12:50 +08:00 via iPhone   ❤️ 3
    推公众号的吧。
    @Livid
    itskingname
        9
    itskingname  
    OP
       2019-01-30 00:20:47 +08:00 via iPhone
    @mario85 已 block
    pkookp8
        10
    pkookp8  
       2019-01-30 00:22:49 +08:00 via Android
    这算是运算符重载吧
    你想写成什么样都可以
    lance6716
        11
    lance6716  
       2019-01-30 00:45:55 +08:00 via Android   ❤️ 11
    @itskingname 竟然还反向 b,牛逼牛逼
    junmoxiao
        12
    junmoxiao  
       2019-01-30 00:54:45 +08:00 via Android
    ,,,,,这,,,水平有点低呀
    ETiV
        13
    ETiV  
       2019-01-30 01:30:30 +08:00 via iPhone
    大家还是拒绝服务攻击吧
    leido
        14
    leido  
       2019-01-30 01:37:29 +08:00 via Android
    这是运算符重载,楼主偷换概念
    Trumeet
        15
    Trumeet  
       2019-01-30 07:34:16 +08:00 via Android
    数据类型 数据类型
    master13
        16
    master13  
       2019-01-30 08:18:20 +08:00   ❤️ 6
    那按照楼主这逻辑,a+b=b+a 也不准确,当 a 和 b 都是 str 的时候……

    玩这个有意思吗
    Qzier
        17
    Qzier  
       2019-01-30 08:20:18 +08:00 via iPhone
    废话,+ 对应的是 __add__ 方法,+= 对应的是 __iadd__ 或 __iconcat__ 方法,当然不同,完全取决于你的实现!
    Qzier
        18
    Qzier  
       2019-01-30 08:23:36 +08:00 via iPhone
    补充下 + 对应的方法还有 __concat__,是针对序列类型的
    xiri
        19
    xiri  
       2019-01-30 08:33:13 +08:00 via Android
    这是 python 里面特殊的运算符重载吧,一般说的+=是针对数值运算的。按楼主这样描述,我自己重定义一下,还可以实现其他功能呢
    fan123199
        20
    fan123199  
       2019-01-30 08:41:35 +08:00
    介绍知识点不错,但不要搞个大新闻(常指标题浮夸),因为这个知识点很可能是常识。
    mayne95
        21
    mayne95  
       2019-01-30 08:47:40 +08:00 via Android
    大家都知道🐱和🐶生不出🐱
    cpyhaha
        22
    cpyhaha  
       2019-01-30 08:48:43 +08:00 via Android
    感觉楼主的出发点还是没错的,但是这种问题一般会比较针对初学者吧!来 V2 就挨喷了
    Mirage09
        23
    Mirage09  
       2019-01-30 09:26:48 +08:00   ❤️ 1
    V2EX 该出个 newbie 节点,把这些东西放在这个节点。
    omri
        24
    omri  
       2019-01-30 10:07:42 +08:00
    学习了,感谢楼主
    msg7086
        25
    msg7086  
       2019-01-30 11:19:39 +08:00
    += 和 + 本来就是两个运算符。通常为了不反直觉,都尽量把他们定义成一样的意思。
    你要是喜欢,还能把+定义成-呢。
    以前不是还有人把 true 和 false 的定义对调着玩吗?你是不是又要说 true 等价于 false 呢。
    tabris17
        26
    tabris17  
       2019-01-30 11:26:14 +08:00
    a += 1
    应该等价于
    a = a + 1

    如果不等价,那就是实现上有问题,属于副作用
    Livid
        27
    Livid  
    MOD
       2019-01-30 14:01:38 +08:00
    @Mirage09 谢谢。我们有这个节点:

    /go/newbie
    Livid
        28
    Livid  
    MOD
       2019-01-30 14:02:06 +08:00
    @itskingname 营销内容只能发到这个节点:

    /go/promotions

    这个主题已经被移动。
    Mirage09
        29
    Mirage09  
       2019-01-30 14:06:43 +08:00 via iPhone
    @Livid 还真的有😂疏忽了
    itskingname
        30
    itskingname  
    OP
       2019-01-30 14:50:08 +08:00
    @Livid 感谢站长提醒。不过这篇文章我确实没有推销东西啊。博客上面的二维码是每篇文章自动添加的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1047 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:23 · PVG 07:23 · LAX 15:23 · JFK 18:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.