近日辞职待工,没有实际的项目与大家分享。暂写写在实际运用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. G - Preparing for Exams

    题目链接: https://vjudge.net/contest/251958#problem/G 具体思路: 圆内四边形内角互补,所以,如图所示. 证明,三角形oda和三角形obc相似. 第一步,角 ...

  2. 如何调整cell的大小

    一般情况下,我们使用tableview的时候从来没有设置过cell的大小(w,h).位置(x,y)等,而是系统直接给我们自动生成,但是有的时候我们可能会改动cell的大小及位置,比如:在适配ios6跟 ...

  3. JDK7与8内存参数解析与修改

    JDK内存 jdk内存实际是jvm内存,jvm有一个运行时数据区,其实就是对这一部分的大小分配. 运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Jav ...

  4. 【逆向工具】使用x64dbg+spy去除WinRAR5.40(64位)广告弹框

    1 学习目标 WinRAR5.40(64位)的弹框广告去除,由于我的系统为x64版本,所以安装了WinRAR(x64)版本. OD无法调试64位的程序,可以让我熟悉x64dbg进行调试的界面. 其次是 ...

  5. 设置linux新用户默认当前目录及使用的shell

    切换到root用户,直接修改/etc/passwd文件,找到你的用户名你一行,如下图所示修改路径,然后保存即可.

  6. 提高delete效率方法

    1 open c_1;   loop     fetch c_1 bulk collect       into t2 limit 100000;     exit when c_1%notfound ...

  7. TOMCAT服务器配置域名

    最近做了个网站,用的是web'服务器是tomcat,框架式SpringMVC,功能做好后,就准备上线使用了, 手上已经有域名以及一台服务器,已经绑定好ip了,剩下的也就是配置Tomcat了,比较简单, ...

  8. Android 动画:你真的会使用插值器与估值器吗?

    目录   目录 1. 插值器(Interpolator) 1.1 简介 定义:一个接口 作用:设置 属性值 从初始值过渡到结束值 的变化规律 如匀速.加速 & 减速 等等 即确定了 动画效果变 ...

  9. gulp-px2rem-plugin 插件的一个小bug

    最近在使用这个插件的过程中发现一个bug: 不支持 含有小数的形式. 查看源码后,修改了下其中的正则,使其支持小数形式(66.66px..6px ). 作者的源码最近一次更新都在两年前,所以就简单的记 ...

  10. Mac配置Java开发环境

    笔者从Window上转到Mac上做开发,一切配置都要重新开始,开发环境配置介绍如下: 1. 下载JDK 从下面链接选择合适版本的安装包进行下载...笔者下载的是jdk-9.0.1 链接:http:// ...