Python中深浅拷贝 垃圾回收与 super继承(六)
1 python拷贝
深拷贝,浅拷贝 与引用三者的区别
import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象
b = a #赋值,传对象的引用
c = copy.copy(a) #对象拷贝,浅拷贝
d = copy.deepcopy(a) #对象拷贝,深拷贝
a.append(5) #修改对象a
a[4].append('c') #修改对象a中的['a', 'b']数组对象
print('a = ', a)
print( 'b = ', b)
print( 'c = ', c)
print('d = ', d)
输出结果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5] #a执行两次值追加操作
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5] #赋值是对象的引用,b指向仍然是a,因此与a内容保持一致
c = [1, 2, 3, 4, ['a', 'b', 'c']] #对象的浅拷贝外部list重新生成新的空间,但是嵌套数组的内存地址不变
d = [1, 2, 3, 4, ['a', 'b']] #深拷贝是所有的数组都新生成一个内存空间,与原来的脱离关系
2 python的垃圾回收机制
Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。
1 引用计数
PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。
优点:
- 简单
- 实时性
缺点:
- 维护引用计数消耗资源
- 循环引用
2 标记-清除机制
基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。
3 分代技术
分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。
Python默认定义了三代对象集合,索引数越大,对象存活时间越长。
举例:
当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。
3 python中 is与 == var与let
is比较的是两者的内存地址 ==基本比较的是两者的数值
is判定
判定值相等,内存地址也相等
a = 10
b = 10
a is b
Ture 常用的1-256计算机共用一个内存地址
a = 9999999
b = 9999999
a is b
False 数值较大的数类似长整型,计算机会生成新的内存地址
var与let
var 定义的变量可以重新被定义
let 定义的变量不能重新被定义
4 Python中 read readline readlines
read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中
readline 读取下一行,使用生成器方法,返回字符串的对象
readlines 读取整个文件到一个迭代器以供我们遍历
#read
f = open("a.txt")
lines = f.read()
print(lines)
print(type(lines))
f.close()
#输出
# hello
# python!
<type 'str'> #字符串类型
#readline
f = open("a.txt")
line = f.readline()
print(type(line))
while line:
print line,
line = f.readline()
f.close()
#输出
#<type 'str'>
<type 'str'> #字符串类型
# hello
# python!
#readlines
f = open("a.txt")
lines = f.readlines()
print(type(lines))
for line in lines:
print(line)
f.close()
#输出
<type 'list'>
# hello
# python!
5 python2 与 python3 的区别
| contents | python3 说明 |
|---|---|
| print函数 | python3 打印带括号 |
| 整除 | / 可以得到浮点数 |
| Unicode | Unicode (utf-8) 字符串 |
| xrange模块 | 统一使用range,并新增__contains__ |
| Raising exceptions/Handling exceptions | raise 与 as 关键字 |
| next()函数 | 只保留next(), .next() 抛出属性异常 |
| for循环 | for 循环变量不会再导致命名空间泄漏 |
| 比较不可排序类型 | python不支持不同类型的比较 |
| 输入input | 只允许input,取消了raw_input |
6 Python必须学会的super
(1) super() 继承方法
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现
class Animal(object): #Animal为父类
def __init__(self, name):
self.name = name
def greet(self):
print 'Hello, I am %s.' % self.name
class Dog(Animal): #Dog为子类
def greet(self): #Dog重定义了greet方法并继承了父类的方法
super(Dog, self).greet() # Python3 可使用 super().greet()
print 'WangWang...'
>>> dog = Dog('dog') #实例化
>>> dog.greet() #调用greet方法
Hello, I am dog.
WangWang..
(2) super初始化
super 的一个最常见用法可以说是在子类中调用父类的初始化方法
class Base(object):
def __init__(self, a, b):
self.a = a
self.b = b
class A(Base):
def __init__(self, a, b, c):
super(A, self).__init__(a, b) # 初始化子类继承父类super(子类名,self).__init__(父类参数)
self.c = c
Python3 可使用 super().__init__(a, b),这样子类继承父类的属性的同时,有保持了自身独有的属性.
(3) 深入super
super其实与父类没有实质的关联
class Base(object):
def __init__(self):
print "enter Base"
print "leave Base"
class A(Base): #继承base
def __init__(self):
print "enter A"
super(A, self).__init__()
print "leave A"
class B(Base): #继承base
def __init__(self):
print "enter B"
super(B, self).__init__()
print "leave B"
class C(A, B): #多重继承自A,B
def __init__(self):
print "enter C"
super(C, self).__init__() #super第一个参数可以是继承链中任意类名字
print "leave C"
#输出
>>> c = C()
enter C
enter A
enter B
enter Base
leave Base
leave B
leave A
leave C
按我们的理解,enter A下面输出应该是基类base中enter base,为什么是enter B ?? 原因是super跟父类没有什么关联,因此执行的顺序是A-->B-->Base
执行过程是:
初始化C()时,先会去调用A的构造方法中的 super(A, self).__init__(), super(A, self)返回当前类的继承顺序中A后的一个类B;然后再执行super(B,self).__init()__,这样顺序执行下去。
super方法可以看出:super()的第一个参数可以是继承链中任意一个类的名字,
1 如果是本身就会依次继承下一个类;
2 如果是继承链里之前的类便会无限递归下去;
3 如果是继承链里之后的类便会忽略继承链汇总本身和传入类之间的类;
Python中深浅拷贝 垃圾回收与 super继承(六)的更多相关文章
- python闭包&深浅拷贝&垃圾回收&with语句
1. 闭包 1.闭包概念 1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包 2. 一般情况下,在我们认知当中,如果一个函数结 ...
- python深浅拷贝&垃圾回收&上下文管理(with语句)
深浅拷贝 在Python中使用copy模块用于对象的拷贝操作. 该模块提供了两个主要的方法:浅拷贝 copy.copy() 深拷贝 copy.deepcopy() 1.浅拷贝(copy) 浅拷贝: 不 ...
- 图解Python中深浅拷贝
在工作中,常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题.为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用.为了生成这个副本,就产生了拷贝.今天就 ...
- python中深浅拷贝
python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...
- Python 内存管理与垃圾回收
Python 内存管理与垃圾回收 参考文献:https://pythonav.com/wiki/detail/6/88/ 引用计数器为主标记清除和分代回收为辅 + 缓存机制 1.1 大管家refcha ...
- Python的深浅拷贝
Python的深浅拷贝 深浅拷贝 1. 赋值,对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量并不是复制一份内容 list1 = [']] list2 = list1 p ...
- Python原理 -- 深浅拷贝
python原理 -- 深浅拷贝 从数据类型说开去 str, num : 一次性创建, 不能被修改, 修改即是再创建. list,tuple,dict,set : 链表,当前元素记录, 下一个元素的位 ...
- Python之深浅拷贝
拷贝就是拷贝,何来深浅之说? Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果 其实这个是由于共享内存导致的结果 浅拷贝 l1 = [1,2,3 ...
- python之MRO和垃圾回收机制
一.MOR 1.C3算法简介 为了解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题. python2.3版本之后不管是新式类还是经典类,查找继承顺序都采用C3算法 2.算法原理 C3算法的 ...
随机推荐
- 教你搭建SpringSecurity3框架(附源码)
源码下载地址:http://pan.baidu.com/s/1qWsgIg0 一.web.xml <?xml version="1.0" encoding="UTF ...
- UVA - 10298 后缀数组(仅观赏)
题意:求最小循环节 \(KMP\)可以20ms通过,而\(da\)实现的后缀数组并无法在3000ms内通过 听说要用\(dc3\)才勉强卡过,这里仅列出\(da\)实现 #include<ios ...
- POJ - 1456 贪心 堆常用操作 注意细节
题意:给定n个商品的deadline和profit,求每天卖一件的情况下的最大获利 显然是一道贪心 按deadline从小到大排序好,动态维护小根(profit)堆的大小<=当前deadline ...
- Js与标签属性
关于在JS中设置标签属性 2017-10-09 23:04 by 清风221, 12790 阅读, 0 评论, 收藏, 编辑 Attribute 该属性主要是用来在标签行内样式,添加.删除.获取属性. ...
- mysql - VARCHAR与VHAR的区别
一, 基本介绍 char 和 varchar 两类型类似, 用来存储字符串,不同之处来自于他们的保存和检索的差别, char 属于固定的长度字符类型, 而varchar 属于可变长度的字符类型 值 C ...
- 昨天太晚了,今天教你用Debug模式来分析程序执行顺序
还是以昨天的XML文件解析来做栗子,希望通过这个好吃的栗子可以举一反三 学会用debug来看源码和找Bug 事件类型主要有五种START_DOCUMENT:xml头的事件类型 = 0END_DO ...
- pulic——function(下载的公共的)
1. /* * 用途: 对Date的扩展,将 Date 转化为指定格式的String */ // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年( ...
- 使用awstat分析Nginx的访问日志
在我的上一篇文章<使用 Nginx 提升网站访问速度>中介绍了 Nginx 这个 HTTP 服务器以及如何通过它来加速网站的访问速度.在实际的网站运营中,我们经常需要了解到网站的访问情况, ...
- java版两人聊天程序
server.java import java.io.*; import java.net.*; import java.text.SimpleDateFormat; import java.util ...
- ArrayList集合长度的问题
// 每次集合中实际包含的元素个数(count)超过了可包含元素的个数capcity //的时候集合就会向内存中申请多开启一倍的空间,来保证集合长度够用 static void Main(strin ...