前言

Python 的链式赋值是一种简易型批量赋值语句,一行代码即可为多个变量同时进行赋值。

例如:

x = y = z = 1

链式赋值是一种非常优雅的赋值方式,简单、高效且实用。但同时它也是一个危险的糖衣炸弹,值得我们引起关注。

面试题:求链式赋值语句中变量 x 的值?

x = [1, 2, 3, 4, 5]
i = 0
i = x[i] = 3
  • 如果你有过 C 语言的编程经验,那么你的思维习惯可能会让你得出这样的结果:x[0] 被赋值为 3,然后 i 再被赋值为 3,所以变量 x 的值为 [3, 2, 3, 4, 5]
  • 但实际上正确的答案却是:变量 i 首先被赋值为 3,然后 x[3] 再被赋值为3,所以最终变量 x 的值为 [1, 2, 3, 3, 5]

从上述结果的表现可以看出二者的区别为:C 语言的赋值顺序是 自右往左* 依次进行的,而 Python 则相反。*

造成这种表征区别的本质原因是由于 C 语言是一种「值语义」类型语言,而 Python 是「对象语义」类型语言。

值语义类型编程语言

值语义指使用系统标准的拷贝方式将一个源对象拷贝成为目标对象后,源对象与目标对象之间毫无关系,彼此独立存在,改变互不影响。

从这一特性出发, C 语言的赋值语句被设计成了具有返回值的表达式,如此才能够保证在链式赋值中所有的对象最终都是彼此独立的。

例如:

x = (y = 1)

表达式 y = 1 在将数值 1 赋值给对象 y 之后返回了数值 1 ,最后再将返回的数值 1 赋值给对象 x。虽然两次赋值操作的数值都是 1,但实际上 x 和 y 对象在内存中的地址是不相同的,所以 x 和 y 彼此独立。

对象语义类型编程语言

对象语义,也称为引用语义。指使用系统标准的拷贝方式将一个源对象拷贝成为目标对象后,源对象与目标对象之间依然共享底层资源,对任意一方的改变都将影响到另一方。

由于不需要像 C 语言那般要求对象之间的独立性。所以,Python 的赋值语句就仅仅是一条语句,而非表达式,也就不存在返回值。在 Python 的定义中,表达式是由操作符(Operator)连接而成的语句,但等号 = 并不属于 Python 的操作符,而是分隔符(Delimiters)。所以下列语句在 Python 中是非法的。

In : x = (y = 1)
File "<ipython-input-6-f6b416f5f895>", line 1
x = (y = 1)
^
SyntaxError: invalid syntax

因为 y = 1 并没有返回值,所以最后执行的是将 “没有返回值” 赋值给了变量 x,显然这样的语义是不存在意义的。

最后

从使用的角度来说,我们只需要简单的记住 Python 的链式赋值顺序是 自左往右 的即可。但更重要的是,通过该面试题我们了解到了 Python 实现的语义类型为对象语义,以及对象语义和值语义的区别。这非常有助于我们以后理解、解决或避免 Python 大多数隐含的坑。

Python 笔试集(1):关于 Python 链式赋值的坑的更多相关文章

  1. Python 笔试集(4):True + True == ?

    目录 目录 前文列表 面试题True Ture 布尔值 布尔类型是特殊的整数类型 前文列表 Python 笔试集:什么时候 i = i + 1 并不等于 i += 1? Python 笔试集(1):关 ...

  2. python学习(二十一) Python 中的链式赋值

    Python的链式赋值如下:

  3. Python特色的序列解包、链式赋值、链式比较

    一.序列解包 序列解包(或可迭代对象解包):解包就是从序列中取出其中的元素的过程,将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中. 一般情况下要解包的序列包含的元素个数必须与你在等 ...

  4. 第4.7节 Python特色的序列解包、链式赋值、链式比较

    一.序列解包 序列解包(或可迭代对象解包):解包就是从序列中取出其中的元素的过程,将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中. 一般情况下要解包的序列包含的元素个数必须与你在等 ...

  5. Python链式赋值执行顺序及执行方式的证明

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在<关于Python链式赋值的赋值顺序问题& ...

  6. 关于Python链式赋值的赋值顺序问题

    在<第4.7节 Python特色的序列解包.链式赋值.链式比较>一文中,老猿这样介绍的: 链式赋值是用一行语句将多个变量赋值为同一个值,语法如下: 变量1=变量2=变量n=赋值表达式 该语 ...

  7. pyhton链式赋值在可变类型/不可变类型上的区别以及其本质

    关于链式赋值的一些注意点: a=[]b=[]x=y=[]print(a==b) #Trueprint(x==y) #Trueprint(a is b) #Falseprint(x is y) #Tru ...

  8. DataFrame 链式赋值

    在运行以下Python代码时,Pandas抛出SettingWithCopyWarning警告: row_data = df_pred.loc[key] row_data['col'] = new_v ...

  9. python和go对比字符串的链式处理

    一.什么是链式处理 对数据的操作进行多步骤的处理称为链式处理,链式处理器是一种常见的编程设计,链式处理的开发思想将数据和操作拆分,解耦,让开发者可以根据自己的技术优势和需求,进行系统开发,同时将自己的 ...

随机推荐

  1. Node.js 最早 npm 包 request 将被废弃

    相信 Node.js 开发者对 Request 都不会陌生,这是一个 Node.js 模块,以 npm 包的形式提供,是一个简单的 HTTP 客户端,通过它可方便地实现 HTTP 请求. 可以看到,r ...

  2. pycharm使用已经配置好的virtualenv环境

    前面已经介绍过基本的virtualenv使用方法,如想要了解的同学可以跳转https://www.cnblogs.com/weilijie/p/10964872.html 下面进入正题,我使用的是py ...

  3. 我来说说XML文件中的xmlns、xmlns:xsi和xsi:schemaLocation、dtd文件的具体含义

    文章摘自:https://yq.aliyun.com/articles/40353               http://www.cnblogs.com/zhao1949/p/5652167.ht ...

  4. Ubuntu 16.04 编译ORB_SLAM2_modified

    编译g2o_with_orbslam2 1.修改g2o/types/slam2d/edge_se2_pointxy_bearing.cpp t.setRotation(t.rotation().ang ...

  5. javaweb 项目编码格式设置

  6. 谈谈对AQS的一些理解

    AQS的概念 AQS全称AbstractQueuedSynchronizer,是java并发包中的核心类,诸如ReentrantLock,CountDownLatch等工具内部都使用了AQS去维护锁的 ...

  7. vue打包多页报错webpackJsonp is not defined

    找到build→webpack.prod.conf.js→找到HtmlWebpackPlugin插件,添加如下配置即可 chunks: ['manifest', 'vendor', 'app']

  8. 指数家族-Beta分布

    2. Beta分布 2.1 Beta分布 我们将由几个问题来得引出几个分布: 问题一:1:  2:把这个  个随机变量排序后得到顺序统计量  3:问  是什么分布 首先我们尝试计算  落在一个区间   ...

  9. 对0.5px的边的研究--------------引用

    什么是像素? 像素是屏幕显示最小的单位,在一个1080p的屏幕上,它的像素数量是1920 1080,即横边有1920个像素,而竖边为1080个.一个像素就是一个单位色块,是由rgba四个通道混合而成. ...

  10. sqljob

    http://blog.csdn.net/sinat_16998945/article/details/52586687