Python高级知识点
“A quitter never wins and a winner never quits” — Napoleon Hill
3.1 垃圾回收
垃圾回收是在正在运行的程序中查找将来无法访问的数据对象,并回收那些对象所使用的资源(尤其是内存)的过程。 自动垃圾收集的语言--Java,C#,Python和大多数脚本语言。 C是没有垃圾回收的语言-程序员需要了解何时应该分配和回收内存。
- 大多数垃圾回收语言都使用引用计数(reference counting,跟踪对象的引用数量)或可达性分析(tracing,从“根”对象开始,查找可被一系列引用访问的对象,剩下没有被引用的对象将被视作“垃圾”被回收)。
- Python使用引用计数,好处是当引用计数变为0时,它可以立即回收对象。这样做的代价是需要为每个对象存储一个附加的整数值。可达性分析(Java中使用)的好处是可以在独立的线程中执行,从而提高性能。缺点是,当垃圾收集器运行时,程序会暂停所有的线程。
- 引用计数的缺点是无法解决“循环引用”,例如:对象A和对象B互相引用,
A.x = B
和B.y = A
,这样会引用计数不会变到1以下,即使没有其它的对象引用A和B,在这种情况下,垃圾收集器会定期查找并删除它们。 - 垃圾收集器使用启发式方法提高速度。 例如,根据经验,最近创建的对象更有可能死掉。 因此,在创建对象时,将它们分配给不同的代,然后首先检查年轻的代。
3.2 深拷贝和浅拷贝
参看之前的文章:学习Python一年,这次终于弄懂了浅拷贝和深拷贝
问:浅拷贝和深拷贝的区别?
答:
-
copy.copy(x)
和copy.deepcopy(x)
,浅拷贝将构造一个新的复合对象,然后(在可能的范围内)将对原始对象中找到的对象的引用插入其中。 深拷贝将构造一个新的复合对象,然后递归地将原始对象中的对象的副本插入其中。 - 浅拷贝和深拷贝之间的区别仅与复合对象有关,复合对象即包含其他对象(例如列表或类实例)的对象。
- 如果已知客户端不会改变对象,可以少用copy。类似地,如果对象本身是不可变的,例如tuple,则无需拷贝它。
3.3 迭代器和生成器
问:迭代器和生成器的区别?
迭代器: 一个实现了__iter__()
和__next__()
方法的对象。第一个方法返回迭代器对象本身,并在for和in语句中使用。第一个方法在迭代中返回下一个值,如果没有更多的元素,将引发StopIteration
异常。
生成器: 创建迭代器的简便方法,使用关键字yield
。生成器使用函数调用堆栈隐式存储迭代器的状态-与编写与作为显式类相同的迭代器相比,可以简化迭代器的编写。 它还有助于提高可读性。
每个生成器都是一个迭代器,但反过来就不正确。 特别是,迭代器可以是完全成熟的类,因此可以提供其他功能。 例如,在上面的迭代器类中添加一个方法来更改迭代限制很容易,这对于生成器是不可能的。
3.4 装饰器 @decorator
@
符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作
import time
def time_function(f):
def wrapper(*args, **kwargs):
begin = time.time()
result = f(*args, **kwargs)
end = time.time()
print("Function call with argument {all_args} took ".format(
all_args="t".join((str(args), str(kwargs)))) + str(end - begin) +
" seconds to execute.")
return result
return wrapper
3.5 List vs. tuple
Lists[1, 4, 7, "apple", 4]
, Tuple(3.14, "PI", 2,43, "e")
相同点:都是容器,且都能存放不同类型的数据,都能进行索引进行访问a[i]
不同点: 元组的是不可变的,不能改变索引a[i]
的值,也不能从元组中增加/删除元素;但是列表可以。
不可变带来的好处:性能提升,容器友好,线程安全。元祖可以放在集合set
中并用作键值,但列表不行。创建元组和访问速度稍快,并且内存占用量较小。
3.6 *args 和 *kwargs
都是用于函数中传递可变参数。*arg
用于传递可变长度的参数列表:
- 在函数中引用的参数称为
args
并不重要-它也可以称为A
或varargs
,args
是习惯用法; -
*
必须跟着常规参数后面
第二个参数** kwargs
在将可变数量的关键字参数传递给函数时使用。
- 将函数中引用的参数称为
args
并不重要,也可以将其称为D或argdict。 -
**
参数必须出现在所有常规命名参数和*
参数之后 - 关键字实参与命名实参有很大不同,其中命名实参的名称在函数本身中指定
3.7 错误处理、异常机制
3.8 lambda
increment_by_i = [lambda x: x + i for i in range(10)]
print(increment_by_i[3](4))
该程序将打印13(= 9 + 4),而不是预期的7(= 3 + 4)。 这是因为在循环中创建的函数具有相同的作用域。 它们使用相同的变量名称,因此,它们都引用相同的变量i,在循环末尾为10,因此为13(= 9 + 4)。
有很多方法可以得到所需的行为。 合理的方法是从函数返回lambda,从而避免命名冲突。
3.9 函数参数
什么是函数的位置参数,关键字参数和默认参数。
- 物化视图刷新结合ADG的尝试(二)(r8笔记第57天)
- python 下利用os模块创建目录以及巧妙使用if not os.path.exits()创建
- Python读取json文件,并转化为字典进行提取字段(出现索引must be int,not str)解决方案
- Python 把字典的key和value的值取出来,按照顺序存入到list中
- Go语言 如果实现http重连?
- python strip()函数 删除字符串中无空白字符或者是无用字符
- 闪回归档的简单测试(r8笔记第68天)
- sql语句查询到整个数据库的容量
- 神奇的go语言
- 备库查询导致的ORA-01110错误及修复(r8笔记第67天)
- SQL客户端DBvisualize直接导入数据出现中文乱码
- Python基础整理操作积累
- 让AI给颜值打分?应该是最公正的裁判了!
- orion的简单测试 (r8笔记第75天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- centos6.5通过yum安装nginx
- Linux系统利用cp命令实现强制覆盖功能的方法
- leetcode队列之设计循环双端队列
- Centos7学习之添加用户和用户组的方法
- Linux静态库与动态库实例详解
- Linux字符终端如何用鼠标移动一个红色矩形详解
- Linux中出现“No space left on device”错误的排查与解决方法
- 浏览器是如何调度进程和线程的?
- Linux shell利用sed如何批量更改文件名详解
- linux下通过xinetd服务管理 rsync 实现开机自启动
- linux实现自动删除最旧的几个文件详解
- 基于Ubuntu 16.04设置固定IP的方法教程
- CentOS添加和删除用户以及用户组的方法
- Linux下使用inode删除指定文件方法示例
- Apache虚拟目录配置及vue-cli反向代理的设置方法