近日辞职待工,没有实际的项目与大家分享。暂写写在实际运用python中遇到的关于可变对象和不可变对象的坑。

首先我们需要明确一个概念,在python中一且皆对象。我们一般定义一个变量a=0,其实质a是一个类型变量,python 会把a封装为一个pyObject。我后面会用type方法来说明这个问题。

说在前面,在python 中变量名是一个类似标签的东西。它之前是什么类型与它之后是什么类型完全没有关系。我们可以把它理解为一个贴纸,可以随意从区块A撕下来贴到区块B上。正因为有这个特点,我们在使用python 对变量赋值时就无需担心变量类型问题。当然,为了规范和后面代码维护方便,此种做法需要节制,不然会让自己都搞不清最终需要的对象到底个什么类型,不方便调程序。

不可变对象

不可变对象一般包括int, float, bool, str, tuple. 不可变对象在函数调用过程中不会被更改,除非重新赋值。

这个例子中,a的类型为 int 说明它是一个类实例对象,根据python官方文档https://docs.python.org/3/library/functions.html#int,显示 class int ,进一步证实我们开篇提到的问题。 我们看到将变量a传入函数addTwoNum 中,将a+b的值赋给a并返回。从结果上看a的值并没有发生改变。我们在来看看各个变量的id。

这里我们看到,a 和 c 的id 不一样,说明它们是两个独立的存储区域。我们在看另一种写法。

这里我们看到,a 的id发生了变化,而且巧合的是现在的a 的id和 c 一样。说明此时a 的指向已经发生了改变。通过这个例子我们可以下这么个结论:不可变对象的存储区域相互独立。每次产生以个新的不可变对象则重新开辟一块区域。

可变对象

可变对象主要包括:list, dict, set。可变对象在参数传递过程会被改变。下面给出一个简单的例子:

我们看到,函数的返回类型什么也没有,但是li 列表的值确实发生了变化,我们还观察到一个很有意思的事,li 中元素的id 值都顺延了,不知道是不是由于li 中值时连续的整数的原因。为了证明li 的首部没有变,及li 本身指向的区块没有变,我们加入打印li 的id 的语句

从图上可以发现,li 的id 确实没有改变。从而可以说明li 没有变,但其值发生了变化。

运用

在知道了不可变对象和可变对象的特性后 ,我们可以根据它们各自的特点避免一些坑,特别是可变对象。在申明函数时,若函数参数存在可变变量,如果不需要每次都产生新的存储空间,我们可以不用另加判断,其中特别需要注意的函数中的局部变量一定不能与全局变量重名。如果需要每次都产生新的存储空间,那么最好是在函数内部声明一个变量,然后最后返回。例如,第一种情况,不需要每次都产生新的存储空间。

每执行一次函数,li 就增加两个元素。这种特性,用在递归中有很好的效果。给出一个括号匹配的算法,其中就运用到了可变变量这个能不断修改元素、添加元素的特性。

def generateParenthesis(N):
ans = []
def backtrack(S = '', left = 0, right = 0):
if len(S) == 2 * N:
ans.append(S)
return
if left < N:
backtrack(S+'(', left+1, right)
if right < left:
backtrack(S+')', left, right+1) backtrack()
return ans

第二种情况,每次都需要开辟新的存储空间:

虽然不可变变量与可变变量是一个简单的问题,我们也不能小看它呀,有时往往就是这种细小的错误让人抓狂。简单的一篇博文,有不足之处请及时指出,共同进步。

python 中的可变对象与不可变对象的更多相关文章

  1. python中如何统计一个类的实例化对象

    类中的静态变量 需要通过类名.静态变量名 来修改 :通过对象不能修改 python中如何统计一个类的实例化对象?? class Person: #静态变量count,用于记录类被实例化的次数 coun ...

  2. python中的函数的参数和可变参数

    最近在搞python的过程中需要用到给函数传可变参数..所以去网上找前人的帖子学习了一下 为了尊重原作者,这里附上链接:http://www.cnblogs.com/tqsummer/archive/ ...

  3. python中表示False的一些内置对象

    By default, an object is considered true unless its class defines either a __bool__() method that re ...

  4. 《python解释器源码剖析》第6章--python中的dict对象

    6.0 序 元素和元素之间可能存在着某种关系,比如学生姓名和成绩.我希望能够通过学生的姓名找到这个学生的成绩,那么只需要将两者关联起来即可.字典正是这么做的,字典中的每个元素就是一个key:value ...

  5. Python探索记(16)——Python的可变类型与不可变类型

    # @Time : 2017/7/8 17:49 # @Author : 原创作者:谷哥的小弟 # @Site : 博客地址:http://blog.csdn.net/lfdfhl # @DESC : ...

  6. 【Python核心编程笔记】一、Python中一切皆对象

    Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...

  7. 【转】Python中自定义可迭代对象

    python 中内置的可迭代的对象有 list.tuple.set.dict 等,那么我们自己怎么定义一个可迭代的对象呢?先来段代码吧 import re import reprlib RE_WORD ...

  8. Python中的几种数据类型

    大体上把Python中的数据类型分为如下几类:   Number(数字) 包括int,long,float,complex String(字符串) 例如:hello,"hello" ...

  9. 简单探讨python中的语句和语法

    python程序结构 python"一切皆对象",这是接触python听到最多的总结了.在python中最基层的单位应该就是对象了,对象需要靠表达式建立处理,而表达式往往存在于语句 ...

  10. Python中的传参是传值还是传址?

    传值:在C++中,传值就是把一个参数的值给这个函数,其中的更改不会影响原来的值. 传址:即传引用,直接把这个参数的内存地址传递进去,直接去这个内存地址上进行修改. 但是这些在Python中都没有,Py ...

随机推荐

  1. Python 入门基础16 -- ATM + 购物车

    ATM + 购物车 1.需求分析 2.设计程序以及程序的架构 设计程序的好处: - 扩展性强 - 逻辑清晰 3.分任务开发 4.测试 黑盒: 白盒: 对程序性能的测试 5.上线运行 # Tank -- ...

  2. MySQL或MariaDB忘记root密码

    当我们忘记数据库密码时,我们可以通过如下来修改! 编辑配置文件(提前最好进行备份) 然后重启服务 systemctl restart mariadb 或者 systemctl restart mysq ...

  3. SpringBoot扩展SpringMVC自动配置

    SpringBoot中自动配置了 ViewResolver(视图解析器) ContentNegotiatingViewResolver(组合所有的视图解析器) 自动配置了静态资源文件夹.静态首页.fa ...

  4. MIPI协议学习总结(一)

    一.MIPI 简介: MIPI(移动行业处理器接口)是Mobile Industry Processor Interface的缩写.MIPI是MIPI联盟发起的为移动应用处理器制定的开放标准. 已经完 ...

  5. API 开发平台 dreamfactory,参考SAWAGGER,国外厂家,开源,本地与云部署

    API 开发平台,参考SAWAGGER,国外厂家,本地与云部署:参考  http://swagger.io/commercial-tools/ 1.dreamfactory 梦工厂公司  https: ...

  6. Springboot分模块开发

    这是个spring cloud项目,service-base:基础服务:service-config:配置中心:service-entity:实体类: service-gateway:服务网关:ser ...

  7. Expm 3_2 寻找最邻近的点对

      [问题描述] 设p1=(x1,y1), p2=(x2,y2), … , pn=(xn,yn) 是平面上n个点构成的集合S,设计和实现找出集合S中距离最近点对的算法. 每一个格子最多只能存在一个点, ...

  8. robotium之不标准select控件

    今天写脚本,遇到一个联合查询框 即:下拉框选择,输入框输入搜索条件,点击查询按钮 如图样式: 用uiautomatorviewer查看元素:无ID,无name,无desc 看到这我瞬间尴尬了,该咋办呢 ...

  9. 类(字符串型;日期时间型;Math)

  10. LeetCode(47):全排列 II

    Medium! 题目描述: 给定一个可包含重复数字的序列,返回所有不重复的全排列. 示例: 输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ] 解题思路: 这道 ...