python 中的可变对象与不可变对象
近日辞职待工,没有实际的项目与大家分享。暂写写在实际运用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 中的可变对象与不可变对象的更多相关文章
- python中如何统计一个类的实例化对象
类中的静态变量 需要通过类名.静态变量名 来修改 :通过对象不能修改 python中如何统计一个类的实例化对象?? class Person: #静态变量count,用于记录类被实例化的次数 coun ...
- python中的函数的参数和可变参数
最近在搞python的过程中需要用到给函数传可变参数..所以去网上找前人的帖子学习了一下 为了尊重原作者,这里附上链接:http://www.cnblogs.com/tqsummer/archive/ ...
- python中表示False的一些内置对象
By default, an object is considered true unless its class defines either a __bool__() method that re ...
- 《python解释器源码剖析》第6章--python中的dict对象
6.0 序 元素和元素之间可能存在着某种关系,比如学生姓名和成绩.我希望能够通过学生的姓名找到这个学生的成绩,那么只需要将两者关联起来即可.字典正是这么做的,字典中的每个元素就是一个key:value ...
- Python探索记(16)——Python的可变类型与不可变类型
# @Time : 2017/7/8 17:49 # @Author : 原创作者:谷哥的小弟 # @Site : 博客地址:http://blog.csdn.net/lfdfhl # @DESC : ...
- 【Python核心编程笔记】一、Python中一切皆对象
Python中一切皆对象 本章节首先对比静态语言以及动态语言,然后介绍 python 中最底层也是面向对象最重要的几个概念-object.type和class之间的关系,以此来引出在python如何做 ...
- 【转】Python中自定义可迭代对象
python 中内置的可迭代的对象有 list.tuple.set.dict 等,那么我们自己怎么定义一个可迭代的对象呢?先来段代码吧 import re import reprlib RE_WORD ...
- Python中的几种数据类型
大体上把Python中的数据类型分为如下几类: Number(数字) 包括int,long,float,complex String(字符串) 例如:hello,"hello" ...
- 简单探讨python中的语句和语法
python程序结构 python"一切皆对象",这是接触python听到最多的总结了.在python中最基层的单位应该就是对象了,对象需要靠表达式建立处理,而表达式往往存在于语句 ...
- Python中的传参是传值还是传址?
传值:在C++中,传值就是把一个参数的值给这个函数,其中的更改不会影响原来的值. 传址:即传引用,直接把这个参数的内存地址传递进去,直接去这个内存地址上进行修改. 但是这些在Python中都没有,Py ...
随机推荐
- Java9都快发布了,Java8的十大新特性你了解多少呢?
Java 9预计将于今年9月份发布,这是否会是一次里程碑式的版本,我们拭目以待.今天,我们先来复习一下2014年发布的Java 8的十大新特性. Java 8可谓是自Java 5以来最具革命性的版本了 ...
- tidb 架构 ~Tidb学习系列(2)
一 简介:咱们今天来学习导入数据篇 二 导入数据测试 1 工具 mysqldumper loader 2 下载tidb企业版工具 wget http://download.ping ...
- Android 中查看内存的使用情况集常用adb命令
http://blog.csdn.net/bigconvience/article/details/35553983 http://blog.csdn.net/duantihi/article/det ...
- 【Udacity并行计算课程笔记】- Lesson 2 The GPU Hardware and Parallel Communication Patterns
本小节笔记大纲: 1.Communication patterns gather,scatter,stencil,transpose 2.GPU hardware & Programming ...
- SpringBoot集成监控管理
(1).添加starter依赖 <dependency> <groupId>org.springframework.boot</groupId> <artif ...
- JS实现双击内容变为可编辑状态
在一些网站上我们经常看到交互性很强的功能.一些用户资料可以直接双击出现文本框,并在此输入新的资料即可修改,无需再按确定按钮等.. 我在网上查了很多资料,但都有一个小bug,就是当获取焦点后,光标的位置 ...
- zabbix通过简单命令监控elasticsearch集群状态
简单命令监控elasticsearch集群状态 原理: 使用curl命令模拟访问任意一个es节点可以反馈的集群状态,集群的状态需要为green curl -sXGET http://serverip: ...
- PYTHON-模块-time&datetime-练习 +目录规范
# 作业# 1.请写出规范目录# 并解释各文件夹的作用bin 可执行文件conf 配置文件core 主要业务逻辑db 数据文件lib 库(公共代码 第三方模块)log 日志文件 # 2.改造atm + ...
- selenium webdriver+python基本操作
# -*- coding:utf-8 -*-#导入模块from selenium import webdriver from selenium.common.exceptions import NoS ...
- js改变或添加className
js改变或添加className <style type="text/css"> .newDiv { font-weight: bold; } </style&g ...