python 对象/变量

对象

Every object has an identity, a type and a value.

  1. 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).
  2. An object’s type is also unchangeable. The type() function returns an object’s type (which is an object itself).
  3. 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.
  1. 不可变(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
  1. 可变(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中的id函数到底是什么?

python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域

python 对象/变量&赋值的几点思考的更多相关文章

  1. python变量和变量赋值的几种形式

    动态类型的语言 python是动态类型的语言,不需要声明变量的类型. 实际上,python中的变量仅仅只是用来保存一个数据对象的地址.无论是什么数据对象,在内存中创建好数据对象之后,都只是把它的地址保 ...

  2. Python 变量类型及变量赋值

    在 Python 中,变量不一定占用内存变量.变量就像是对某一处内存的引用,可以通过变量访问到其所指向的内存中的值,并且可以让变量指向其他的内存.在 Python 中,变量不需要声明,但是使用变量之前 ...

  3. Python把同一个对象循环赋值给另外一个变量

    Python把同一个对象循环赋值给另外一个变量,修改一个对象,其他对象也修改了 >>> row=['_'] * 3 >>> board = [] >>& ...

  4. Python比较操作符、变量赋值、对象拷贝

    Python比较操作符.变量赋值.对象拷贝 目录 Python比较操作符.变量赋值.对象拷贝 1. 比较操作符 == 和 is 1.1 区别 1.2 实例 2. 变量及其赋值 2.1 概念和逻辑关系 ...

  5. Python基础0:变量 赋值 表达式和运算符

    变量: 前面我们在使用print()输出内容的时候,如果内容很长,后面要再次输出的时候,就需重新在输入一遍. 如果给输出的内容起个简单的别名.这样我们用简短的别名来代替长内容,下次要输出的时候就直接使 ...

  6. 2.python的变量与赋值

    首先,为何要使用变量这里就不再多说了,我这里就介绍一下变量的命令规则和变量赋值的内存行为. 1.变量的命名规则 变量其实通过一个标记调用内存中的值,而变量名就是这个标记的名称,但是万一这个标记已经被提 ...

  7. Python中变量、赋值、浅拷贝、深拷贝

    https://www.cnblogs.com/LetMe/p/6724555.html 在理解浅拷贝和深拷贝之前,首先要理解学习一下变量在Python中是怎样存储的: 变量的类型是分值引用与地址引用 ...

  8. python的变量,对象的内存地址以及参数传递过程

    作为一个由c/c++转过来的菜鸟,刚接触Python的变量的时候很不适应,应为他的行为很像指针,void* ,不知道大家有没有这样的感觉.其实Python是以数据为本,变量可以理解为标签.作为c/c+ ...

  9. python 中变量和对象

    1. 在 python 中,类型属于对象,变量是没有类型的:a=[1,2,3] a="Runoob"以上代码中,[1,2,3] 是 List 类型,"Runoob&quo ...

随机推荐

  1. 搭建IntelliJ IDEA授权服务

    废话不多,直接开始 下载IntelliJ IDEA授权服务软件v1.4 密码:mu3t 下载IntelliJ IDEA授权服务软件v1.3 密码:1odn 选择你自己服务器的版本,我这里选择Intel ...

  2. Qt学习(一)

    1. 简介 跨平台 GUI 通常有三种实现策略 API 映射 相当于将不同平台的 API 提取公共部分.界面库使用同一套 API,将其映射到不同的底层平台上面.相当于取交集 如wxWidgets. 优 ...

  3. 十九、Node.js-非阻塞IO、异步以及 '事件驱动EventEmitter'解决异步

    1.Nodejs 的单线程 非阻塞 I/O 事件驱动 在 Java.PHP 或者.net 等服务器端语言中,会为每一个客户端连接创建一个新的线程而每个线程需要耗费大约 2MB 内存.也就是说,理论上, ...

  4. adt-bundle-windows不显示ADK Manage和其它图标的解决方法?

    我今天下载了包含ADT的eclipse,运行后发现在工具栏中居然没有ADK Manage和其它Android相关图标,这是为什么啊?上网搜索了一下,最终解决了!解决方法,把ADK的tool路径加入到p ...

  5. “全栈2019”Java第七十八章:内部类可以继承其他类吗?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. 阿里java开发规范学习(附P3C IDEA插件 帮助规范的养成)

    浅析 阿里巴巴 Java 开发规约 (未完成) 更加优秀的页面展现请到浅析 阿里巴巴 Java 开发规约 contents 为什么要学 编程规约 P3C IDEA 插件 why-use 我们知道,一般 ...

  7. 运算符重载入门demo

    #include "pch.h" #include <iostream> using namespace std; class A { public: A(int x, ...

  8. PHP的curl实现get,post 和 cookie (转)

    类似于dreamhost这类主机服务商,是显示fopen的使用 的.使用php的curl可以实现支持FTP.FTPS.HTTP HTPPS SCP SFTP TFTP TELNET DICT FILE ...

  9. oracle12c之二 控制PDB中SGA 与 PGA 内存使用

    oracle12c之 控制pdb中sga 与 pga 内存使用 Memory Management using Resource Manager Oracle数据库资源管理器(资源管理器)现在可以在多 ...

  10. Linux C代码 获取IP地址

    Ubuntu 16.04下,可编译通过: #include <stdio.h> #include <ifaddrs.h> #include <arpa/inet.h> ...