1. Variables Are Not Boxes

# Think variables as sticky notes
a = [1, 2, 3]
b = a
a.append(4)
print b # [1, 2, 3, 4] # 1. The object is created before the assignment. So variable is
# assigned to an object, not the other way around.

2. Identity, Equality, and Aliases

charles = {'name': 'Charles', 'born': 1832}
lewis = charles # alias
print lewis is charles # True
print id(lewis) == id(charles) # True
lewis['born'] = 1844
print charles # {'born': 1844, 'name': 'Charles'} alex = {'name': 'Charles', 'born': 1844}
print alex == charles # True (same value)
print alex is charles # False (different identities) # 1. In CPython, id() returns the memory address of the object, but
# it may be something else in another Python interpreter. The key
# point is that the ID is guaranteed to be a unique numeric label,
# and it will never change during the life of the object.
# 2. The is operator is faster than ==, because it cannot be
# overloaded, so Python does not have to find and invoke special
# methods to evaluate it, and computing is as simple as comparing
# two integer IDs.
# 3. a == b is syntactic sugar for a.__eq__(b). The __eq__ method
# inherited from object compares object IDs, so it produces the
# same result as is. But most built-in types override __eq__ with
# more meaningful implementations that actually take into account
# the values of the object attributes. Equality may involve a lot
# of processing. (large collections / deeply nested structures)
t1 = (1, 2, [30, 40])
t2 = (1, 2, [30, 40])
print t1 == t2 # True
print id(t1[-1]) # 4302515784
t1[-1].append(99)
print t1 # (1, 2, [30, 40, 99])
print id(t1[-1]) # 4302515784
print t1 == t2 # False # 1. What can never change in a tuple is the identity of the
# items it contains.
# 2. Tuples, like most Python collections—lists, dicts, sets,
# etc.--hold references to objects. On the other hand, single-type
# sequences like str, bytes, and array.array are flat: they don’t
# contain references but physically hold their data--characters,
# bytes, and numbers--in contiguous memory.

3. Copies Are Shallow by Default

import copy
l1 = [3, [55, 44], (7, 8, 9)]
l2 = list(l1) # l2 = l1[:] or l2 = copy.copy(l1)
print l2 # [3, [55, 44], (7, 8, 9)]
print l2 == l1 # True
print l2 is l1 # False
l1.append(100)
l1[1].remove(55)
print l1 # [3, [44], (7, 8, 9), 100]
print l2 # [3, [44], (7, 8, 9)]
l3 = copy.deepcopy(l2)
l3[1].append(55)
print l3 # [3, [44, 55], (7, 8, 9)]
print l2 # [3, [44], (7, 8, 9)] # 1. Using the constructor or [:] or copy.copy() produces a shallow copy.

# Cyclic references
a = [10, 20]
b = [a, 30]
a.append(b)
print a # [10, 20, [[...], 30]]
c = copy.deepcopy(a)
print c # [10, 20, [[...], 30]]

[Notes]: You can control the behavior of both copy and deepcopy by implementing the __copy__() and __deepcopy__() special methods as described in the copy module documentation.

4. Function Parameters as References

def f(a, b):
a += b
return a x = 1
y = 2
print f(x, y) # 3
print x, y # 1 2
a = [1, 2]
b = [3, 4]
print f(a, b) # [1, 2, 3, 4]
print a, b # [1, 2, 3, 4] [3, 4]
t = (10, 20)
u = (30, 40)
print f(t, u) # (10, 20, 30, 40)
print t, u # (10, 20) (30, 40) 1. The only mode of parameter passing in Python is call by sharing.
which means the parameters inside the function become aliases
of the actual arguments.
2. The result of this scheme is that a function may change any
mutable object passed as a parameter, but it cannot change the
identity of those objects class A:
def __init__(self, a_list=[]):
self.a_list = a_list
def add(self, name):
self.a_list.append(name) a1 = A()
a1.add('A')
print a1.a_list # ['A']
a2 = A()
a2.add('B')
print a2.a_list # ['A', 'B']
print a1.a_list # ['A', 'B']
print a1.a_list is a2.a_list # True
print A.__init__.__defaults__[0] is a1.a_list # True # 1. Two objects don’t get an initial list end up sharing the same
# list among themselves.
# 2. When the module is loaded, and the default values become
# attributes of the function object. So if a default value is a
# mutable object, and you change it, the change will affect every
# future call of the function. class B:
def __init__(self, a_list=None):
if a_list is None:
self.a_list = []
else:
self.a_list = a_list
# self.a_list = list(a_list) # make a copy
def add(self, name):
self.a_list.append(name) l = [1, 2, 3]
b1 = B(l)
b1.add(5)
print b1.a_list # [1, 2, 3, 5]
print l # [1, 2, 3, 5] # 1. You should think twice before aliasing the argument object
# by simply assigning it to an instance variable in your class.
# If in doubt, make a copy.

5. del and Garbage Collection

  • The del statement deletes names, not objects. An object may be garbage collected as result of a del command, but only if the variable deleted holds the last reference to the object, or if the object becomes unreachable. Rebinding a variable may also cause the number of references to an object to reach zero, causing its destruction.
  • unreachable: If two objects refer to each other, they may be destroyed if the garbage collector determines that they are otherwise unreachable because their only references are their mutual references.
  • There is a __del__ special method, but it does not cause the disposal of the instance, and should not be called by your code. __del__ is invoked by the Python interpreter when the instance is about to be destroyed to give it a chance to release external re‐sources. You will seldom need to implement __del__ in your own code

  • In CPython, the primary algorithm for garbage collection is reference counting. Es‐sentially, each object keeps count of how many references point to it. As soon as that refcount reaches zero, the object is immediately destroyed: CPython calls the __del__ method on the object (if defined) and then frees the memory allocated to the object. In CPython 2.0, a generational garbage collection algorithm was added to detect groups of objects involved in reference cycles—which may be unreachable even with outstanding references to them, when all the mutual references are contained within the group. Other implementations of Python have more sophisticated garbage collectors that do not rely on reference counting, which means the __del__ method may not be called immediately when there are no more references to the object.

import weakref
s1 = {1, 2, 3}
s2 = s1
def bye():
print('Gone with the wind...')
ender = weakref.finalize(s1, bye)
print(ender.alive) # True
del s1
print(ender.alive) # True
s2 = 'spam' # Gone with the wind...
print(ender.alive) # False # 1. del does not delete objects, but objects may be deleted
# as a consequence of being unreachable after del is used.
# 2. This works because final ize holds a weak reference to {1, 2, 3}.

6. Weak References

P236

7. Tricks Python Plays with Immutables

P240

8. Object References, Mutability, and Recycling的更多相关文章

  1. 《流畅的Python》Object References, Mutability, and Recycling--第8章

    Object References, Mutability, and Recycling 本章章节: Variables Are Not Boxes identity , Equality ,  Al ...

  2. object references an unsaved transient instance - save the transient instance before flushing错误

    异常1:not-null property references a null or transient value解决方法:将“一对多”关系中的“一”方,not-null设置为false(参考资料: ...

  3. ManyToMany【项目随笔】关于异常object references an unsaved transient instance

    在保存ManyToMany  时出现异常: org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.Tran ...

  4. Effective Java 06 Eliminate obsolete object references

    NOTE Nulling out object references should be the exception rather than the norm. Another common sour ...

  5. [SAP ABAP开发技术总结]数据引用(data references)、对象引用(object references)

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. 三大框架常遇的错误:hibernate : object references an unsaved transient instance

    hibernate : object references an unsaved transient instance 该错误是操作顺序的问题,比如: save或update顺序问题---比方学生表和 ...

  7. Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved tran

    今天在使用一对多,多对一保存数据的时候出现了这个错误 Hibernate错误: Exception in thread "main" org.hibernate.Transient ...

  8. ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [object references an unsaved transient instance - save the transient instance before flushing: cn.itcast.domain.Custom

    本片博文整理关于Hibernate中级联策略cascade和它导致的异常: Exception in thread "main" org.hibernate.TransientOb ...

  9. object references an unsaved transient instance save the transient instance before flushing

    object references an unsaved transient instance save the transient instance before flushing 对象引用未保存的 ...

随机推荐

  1. Python3 Selenium自动化web测试 ==> 第一节 起始点之Python单元测试框架 unittest

    前置步骤 Python版本:3.6.4 selenium版本:3.11.0 >>> import selenium >>> help(selenium) IDE:P ...

  2. 【DSP开发】帮您快速入门 TI 的 Codec Engine

    德州仪器半导体技术(上海)有限公司 通用DSP 技术应用工程师 崔晶 德州仪器(TI)的第一颗达芬奇(DaVinci)芯片(处理器)DM6446已经问世快三年了.继DM644x之后,TI又陆续推出了D ...

  3. 【转】Windows 7下用VMware Workstation 10虚拟机安装 Ubuntu 14.04

    一.软件下载 1.VMware Workstation v10.0.1虚拟机官方简体中文版下载(附永久KEY注册密钥) http://www.linuxidc.com/Linux/2012-11/73 ...

  4. error: audit:backlog limit exceeded

    报错场景:telnet.ping.ftp都通的情况下,无法ssh服务器 原因:audit缓冲区设置过小,服务器默认缓冲区大小为320kb 解决办法:可通过auditctl -b 8192设定缓冲区大小 ...

  5. oracle数据库用户之间授权

    今天遇到一个数据库的问题: 系统数据库用户下创建了几个视图用于外部系统开发报表使用,当外部系统提取视图数据时,需要通过一个只能访问需要视图权限的用户,于是想到给他创建一个新的用户,并给这个用户分配只能 ...

  6. centos7 宝塔php7安装mongodb扩展

    一.下载.解压源码 下载地址:https://pecl.php.net/package/mongodb wget -c https://pecl.php.net/get/mongodb-1.5.3.t ...

  7. 利用神器BTrace 追踪线上 Spring Boot应用运行时信息

    概述 生产环境中的服务可能会出现各种问题,但总不能让服务下线来专门排查错误,这时候最好有一些手段来获取程序运行时信息,比如 接口方法参数/返回值.外部调用情况 以及 函数执行时间等信息以便定位问题.传 ...

  8. 【记忆化搜索】Happy Happy Prime Prime

    题目描述 RILEY VASHTEE: [reading from display] Find the next number in the sequence:313 331 367 ...? Wha ...

  9. Windows 证书签名的伪造

    Windows 系统中的一些非常重要文件通常会被添加数字签名,其目的是用来防止被篡改,能确保用户通过互联网下载时能确信此代码没有被非法篡改和来源可信,从而保护了代码的完整性.保护了用户不会被病毒.恶意 ...

  10. 牛客 216D 消消乐 (二分图最小点覆盖)

    大意: 给定棋盘, 每次消除一行或一列, 求最小次数使得消除完所有'*'. 裸的二分图最小点覆盖. 二分图的最小点覆盖等于最大匹配, 输出方案时从所有左部未盖点开始标记交替路上的点, 最后左部所有未标 ...