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 ...
随机推荐
- CentOS中安装Java环境 jdk
一. 在CentOS中只需要先移除自带的OpenJava,再安装原生的Java SDK. <1> rpm -qa | grep jdk: 也就是query all npm 包,找 ...
- plsql连接oracle客户端(简单,实用方案)附件
plsql 连接 oracle 需要在本地安装oracle客户端(附件中下载): 将文件下载下来后,放到任意目录,例如 D:\instantclient_10_2 修改 tnsnames.ora 文件 ...
- 使用InstallUtil安装或卸载服务
使用InstallUtil安装或卸载服务 一.安装服务: C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe D:\MyServ ...
- c# 变量交换
C# 变量交换 变量交换的方法: 1.借助第三个变量: class Program { static void Main(string[] args) { Exchage(,); } /// < ...
- 二十四、MongoDB数据库的使用
首先按照上一篇文章的介绍,启动并连接数据库 然后我们开始学习如何使用MongoDB数据库: 1.创建数据库 第一步,在cmd窗口执行: use dbname dbname是你打算要创建的数据库名称 执 ...
- input 实现onchange效果
$(".selected input").on('input',function(e){ cc.search(); });
- 如何在Linux下禁用IPv6
如何在Linux下禁用IPv6 echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6 禁用IP ...
- P3952 时间复杂度
P3952 时间复杂度 题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机 ...
- P4168 [Violet]蒲公英 区间众数
$ \color{#0066ff}{ 题目描述 }$ 在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关. 为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 \((a_1,a_2.. ...
- 对csrf的理解
用户浏览并登陆信任网站A 通过验证,在用户浏览器产出A的cookie 用户在没有登出A的情况下访问攻击网站B B要求访问第三方站点A,发出一个请求 根据B的请求,浏览器带着A的cookie访问A A不 ...