python 对象/变量&赋值的几点思考
python 对象/变量
对象
Every object has an identity, a type and a value.
- An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity (currently implemented as its address).
- An object’s type is also unchangeable. The type() function returns an object’s type (which is an object itself).
- The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable.
- 不可变(immutable)对象:
numbers, strings and tuples, etc.
可变对象的id基本上可以理解为该对象内存地址,而python中命名空间内的对象总是以标签的方式来操作,例如a=3,它会在内存中寻找一个int类型的value为3的对象,如果有则将其内存地址作为a的id,假如没有这样的对象,则会先新建一个int类型的value为3的对象,再将其内存地址作为a的id。
class Obj():
def __init__(self,arg):
self.x=arg
if __name__ == '__main__':
obj=Obj(1)
print id(obj) #32754432
obj.x=2
print id(obj) #32754432
s="abc"
print id(s) #140190448953184
s="bcd"
print id(s) #32809848
x=1
print id(x) #15760488
x=2
print id(x) #15760464
- 可变(mutable)对象:
dictionaries and lists, etc.、
在python中不可变对象总是唯一的,即使两个列表的大小,value对相同,但他们的id绝不可能相同,这是因为对象是可变的,假如id相同,则两个变量将可以协同变化。
class Obj():
def __init__(self,arg):
self.x=arg
def __eq__(self,other):
return self.x==other.x
if __name__ == '__main__':
obj1=Obj(1)
obj2=Obj(1)
print obj1 is obj2 #False
print obj1 == obj2 #True
lst1=[1]
lst2=[1]
print lst1 is lst2 #False
print lst1 == lst2 #True
s1='abc'
s2='abc'
print s1 is s2 #True
print s1 == s2 #True
a=2
b=1+1
print a is b #True
a = 19998989890
b = 19998989889 +1
print a is b #False
对象赋值
在python中一切皆为对象,赋值操作即是改变命名空间中的相应名字的指针,在相应的对象上即使反映为:从一个对象上撕下标签,再将该标签打到另外一个对象上。
对于可变对象来说,即为id地址的改变。
def fun(a):
print "id(a):", id(a) # 56715624
a = 4
print "id(a):", id(a) # 56715600
print "a:", a
b = 3
print "id(3):", id(3) # 56715624
fun(b)
print "id(b):", id(b) # 56715624
print 'b:', b
首先创建了对象int 3,该对象即有了一个id,再将其赋值给b(属于全局名字空间),b的id与int 3的id相同,所以b指向了3.再进行函数操作fun(b)时,首先进行了a=b=3的操作,a与b与3的id相同,共同指向对象3,然后a又进行了赋值操作,因为对象是不可变的(type决定了),所以必须新建对象int 4,并将a指向4,所以a的id改变了,a的value也相应的改变了。但是b是属于全局名字空间的,b并没有受到影响。
对于可变变量(列表)
def fun(a):
print "id(a):", id(a) # 63265352 a=b的操作,a、b的id相同
print a # [3, [2, 3]]
print id(c) # 57698664 指向全局变量c
a[0] = 1
print "id(a):", id(a) # 63265352 修改了a的value,但是id并未改变
c = 3
b = [c, [2, 3]]
print "id(c):", id(c) # 57698664
print "id(b):", id(b) # 63265352
fun(b)
print "id(b):", id(b) # 63265352
print 'b:', b # [1, [2, 3]] b的id与a相同,a、b的value同时改变
在此处赋值时,先进行a=b的操作,a、b的id相同,所以在fun内改变了a[0],b也被改变了。
def fun(a):
print "id(a):", id(a) # 54309000 由于进行了copy操作,所以相当于传递了一个新的列表id给a,a的id与b则不相同了,
a上的浅层(axis=0)修改对b不起作用,但深层次(axis>0)的修改依然有效吗,这是因为此时a[1]与b[1]都指向同一个列表。
print a[0] is b[0] # False
print a[1] is b[1] # True
print a # [3, [2, 3]]
a[0] = 1
a[1][0] = 0
print a # [1, [0, 3]]
c = 3
b = [c, [2, 3]]
print "id(c):", id(c) # 52455784
print "id(b):", id(b) # 54286920
fun(b[:]) # 对b进行切片操作,即等于copy.copy(b)
print "id(b):", id(b) # 54286920
print 'b:', b # [3, [0, 3]]
对列表的复制会产生一个新的列表,与新的列表id。
切片操作与浅层复制是相等的:a[:] 等价于 copy.copy[a]
深层复制可以迭代copy操作,使得列表中的列表也被复制,即完全产生一个新的value相同的列表,新列表与旧列表没有任何联系,对列表中的列表的修改不会影响原列表。可以写成copy.deepcopy(b)。
Reference
python 对象/变量&赋值的几点思考的更多相关文章
- python变量和变量赋值的几种形式
动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...
- Python 变量类型及变量赋值
在 Python 中,变量不一定占用内存变量.变量就像是对某一处内存的引用,可以通过变量访问到其所指向的内存中的值,并且可以让变量指向其他的内存.在 Python 中,变量不需要声明,但是使用变量之前 ...
- Python把同一个对象循环赋值给另外一个变量
Python把同一个对象循环赋值给另外一个变量,修改一个对象,其他对象也修改了 >>> row=['_'] * 3 >>> board = [] >>& ...
- Python比较操作符、变量赋值、对象拷贝
Python比较操作符.变量赋值.对象拷贝 目录 Python比较操作符.变量赋值.对象拷贝 1. 比较操作符 == 和 is 1.1 区别 1.2 实例 2. 变量及其赋值 2.1 概念和逻辑关系 ...
- Python基础0:变量 赋值 表达式和运算符
变量: 前面我们在使用print()输出内容的时候,如果内容很长,后面要再次输出的时候,就需重新在输入一遍. 如果给输出的内容起个简单的别名.这样我们用简短的别名来代替长内容,下次要输出的时候就直接使 ...
- 2.python的变量与赋值
首先,为何要使用变量这里就不再多说了,我这里就介绍一下变量的命令规则和变量赋值的内存行为. 1.变量的命名规则 变量其实通过一个标记调用内存中的值,而变量名就是这个标记的名称,但是万一这个标记已经被提 ...
- Python中变量、赋值、浅拷贝、深拷贝
https://www.cnblogs.com/LetMe/p/6724555.html 在理解浅拷贝和深拷贝之前,首先要理解学习一下变量在Python中是怎样存储的: 变量的类型是分值引用与地址引用 ...
- python的变量,对象的内存地址以及参数传递过程
作为一个由c/c++转过来的菜鸟,刚接触Python的变量的时候很不适应,应为他的行为很像指针,void* ,不知道大家有没有这样的感觉.其实Python是以数据为本,变量可以理解为标签.作为c/c+ ...
- python 中变量和对象
1. 在 python 中,类型属于对象,变量是没有类型的:a=[1,2,3] a="Runoob"以上代码中,[1,2,3] 是 List 类型,"Runoob&quo ...
随机推荐
- jira项目管理平台搭建
参考文档:http://www.cnblogs.com/ilanni/p/6200875.html 一.环境准备 jira7.2的运行是需要依赖java环境的,也就是说需要安装jdk并且要是1.8 ...
- [Erlang12] Mnesia分布式应用
[Erl_Question12] Mnesia分布式应用 情景: 设计一个图书管理系统,需求: 1. 基本的增删查改功能; 2. 支持多节点备份(其中一个节点挂了进,对外接口不影响). 方案一: Er ...
- [javascript]模块化&命名污染—from 编程精解
最近看了编程精解里面的模块化一章,很受启发. /****************/ 在开发的实际过程中,根据页面或者逻辑布局,js代码可以按照功能划分为若干个区块:数据交互.表单验证.页面布局等等模块 ...
- JS设置localStorage有效期
localStorage是一个没有时间限制的数据存储,如果没有手动删除它,它将永久保存. 但是有些时候我们又需要它在一段时间后自动删除,这里我们可以对它进行扩展. var date = new Dat ...
- ng 发生 Error: ELOOP: too many symbolic links encountered...
ng g component components/home 发生如下提示: 由于使用 cnpm install 安装 node_modules 导致这样. 解决办法: 删除 node_modules ...
- 「HNOI 2013」消毒
题目链接 戳我 \(Solution\) 我们首先想一想如果这一题只是二维的该怎么办? 就是一个最小点覆盖问题.这里就不详细解释了,用网络流或匈牙利都无所谓. 但现在是三维的,那么现在该如何处理呢? ...
- HAOI2010 订货
题目链接:戳我 费用流. 将每天分成早上和晚上两个点.源点向早上连容量INF,费用为进货量的边.早上向汇点连容量供货量,费用0.早上向晚上连容量为S,费用为0的边.晚上向第二天早上连容量S,费用0.之 ...
- Ubuntu16.04实用python脚本 - 启动nautilus(Gnome的文件管理器)!
nautilus是Gnome的图形的文件管理器,可以很方便管理各种文件,但是通常我们不是在root用户下,如果想在root下使用,必须在shell里面输入命令: sudo nautilus 这样做固然 ...
- java操作AWS S3一些坑记录
1,aws sdk jar版本不一致问题 一开始我在pom.xml中只配置了如下aws-java-sdk-s3 <!-- https://mvnrepository.com/artifact/c ...
- ArchLinux下Ecplise软件报错
如果你的Java出现了一下问题:An error has occurred. See error log for more details.java.lang.NullPointerException ...