本文共 5626 字,大约阅读时间需要 18 分钟。
Python 的内存机制呈现金字塔形状,-1,-2 层主要有操作系统进行操作;
第 0 层是 C 中的 malloc,free 等内存分配和释放函数进行操作;
第 1 层和第 2 层是内存池,有 Python 的接口函数 PyMem_Malloc 函数实现,当对象小于
256K 时有该层直接分配内存;第 3 层是最上层,也就是我们对 Python 对象的直接操作;
Python 在运行期间会大量地执行 malloc 和 free 的操作,频繁地在用户态和核心态之间进行切换,这将严重影响 Python 的执行效率。为了加速 Python 的执行效率,Python 引入了一个内存池 机制,用于管理对小块内存的申请和释放。Python 内部默认的小块内存与大块内存的分界点定在 256 个字节,当申请的内存小于 256 字节 时,PyObject_Malloc 会在内存池中申请内存;当申请的内存大于 256 字节时,PyObject_Malloc 的 行为将蜕化为 malloc 的行为。当然,通过修改 Python 源代码,我们可以改变这个默认值,从而改 变 Python 的默认内存管理行为。
调优手段(了解)
1.手动垃圾回收2.调高垃圾回收阈值
3.避免循环引用(手动解循环引用和使用弱引用)
Python 的参数传递有:位置参数、默认参数、可变参数、关键字参数。
函数的传值到底是值传递还是引用传递,要分情况:不可变参数用值传递:
像整数和字符串这样的不可变对象,是通过拷贝进行传递的,因为你无论如何都不可能在原处改变不可变对象可变参数是引用传递的:
比如像列表,字典这样的对象是通过引用传递、和 C 语言里面的用指针传递数组很相似,可变对象能在函数内部改变。Python 中一切皆对象,函数名是函数在内存中的空间,也是一个对象。
在编写代码时只写框架思路,具体实现还未编写就可以用 pass 进行占位,使程序不报错,不会进 行任何操作。
map()函数
# 传入一个参数 def one_p(x): return x * x print 'map1.1:', map(one_p, range(1, 5)) #结果:map1.1: [1, 4, 9, 16] print 'map1.2:', map(one_p, [1, 2, 3, 4, 5, 6]) #结果:map1.2: [1, 4, 9, 16, 25, 36] # 传入多个参数 a = [1, 2, 3, 4, 5] b = [1, 1, 6, 2, 3] c = [1, 2, 3, 4, 5] s = map(lambda (x, y, z): x * y * z, zip(a, b, c)) print 'map2:', s #结果:map2: [1, 4, 54, 32, 75]
reduce()函数
r1 = reduce(lambda x, y: x * y, (2, 2, 6, 2)) # 运算过程:(((2*2)*6)*2) r2 = reduce(lambda x, y: x * y, (2, 2, 6), 2) # 运算过程:(((2*2)*6)*2) print 'r1:', r1 # 结果:r1: 48 print 'r2:', r2 # 结果:r2: 48
回调函数是把函数的指针(地址)作为参数传递给另一个函数,将整个函数当作一个对象,赋值给调 用的函数。
在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为 闭包。
装饰器本质上是一个 Python 函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能。装 饰器的返回值也是一个函数的对象,它经常用于有切面需求的场景。 比如:插入日志、性能测试、事务处理、缓存、 权限的校验等场景 有了装饰器就可以抽离出大量的与函数功能本身无关的雷同代码并发并继续使用。
迭代器是一个更抽象的概念,任何对象,如果它的类有 next 方法和 iter 方法返回自己本身,对于 string、list、 dict、tuple 等这类容器对象,使用 for 循环遍历是很方便的。在后台 for 语句对容器对象调用 iter()函数,iter() 是 python 的内置函数。iter()会返回一个定义了 next()方法的迭代器对象,它在容器中逐个访问容器内元素,next() 也是 python 的内置函数。在没有后续元素时,next()会抛出一个 StopIteration 异常。
**生成器(Generator)**是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用 yield 语句。每次 next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置 和所有的数据值)
**区别:**生成器能做到迭代器能做的所有事,而且因为自动创建了 iter()和 next()方法,生成器显得特别简洁,而且 生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当 发生器终结时,还会自动抛出 StopIteration 异常。
is 判断的是 a 对象是否就是 b 对象,是通过 id 来判断的。
==判断的是 a 对象的值是否和 b 对象的值相等,是通过 value 来判断的。面向对象是相对于面向过程而言的。面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;而面 向对象是一种基于结构分析的、以数据为中心的程序设计思想。在面向对象语言中有一个有很重要东西,叫做类。
面向对象有三大特性:封装、继承、多态。
Process 语法结构:
进程池 Pool
锁(Lock)是 Python 提供的对线程控制的对象。有互斥锁、可重入锁、死锁。
每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
同一个进程中的多线程之间是共享系统资源的,多个线程同时对一个对象进行操作,一个线程操作 尚未结束,另一个线程已经对其进行操作,导致最终结果出现错误,此时需要对被操作对象添加互斥锁, 保证每个线程对该对象的操作都得到正确的结果。
多进程适合在 CPU 密集型操作(cpu 操作指令比较多,如位数多的浮点运算)。 多线程适
合在 IO 密集型操作(读写数据操作较多的,比如爬虫)。
线程是并发,进程是并行;
进程之间相互独立,是系统分配资源的最小单位,同一个线程中的所有线程共享资源。
并行:同一时刻多个任务同时在运行。
并发:在同一时间间隔内多个任务都在运行,但是并不会在同一时刻同时运行,存在交替执行的情
况。实现并行的库有:multiprocessing
实现并发的库有:threading 程序需要执行较多的读写、请求和回复任务的需要大量的 IO 操作,IO 密集型操作使用并发更好。 CPU 运算量大的程序程序,使用并行会更好。IO 密集型:系统运作,大部分的状况是 CPU 在等 I/O (硬盘/内存)的读/写。
CPU 密集型:大部份时间用来做计算、逻辑判断等 CPU 动作的程序称之 CPU 密集型。
在 socket 通信过程中不断循环检测一个全局变量(开关标记变量),一旦标记变量变为关闭,则 调 用 socket 的 close 方法,循环结束,从而达到关闭连接的目的。
UDP 是面向无连接的通讯协议,UDP 数据包括目的端口号和源端口号信息。
优点:UDP 速度快、操作简单、要求系统资源较少,由于通讯不需要连接,可以实现广播发送 缺点:UDP 传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数 据是否会正确接收,也不重复发送,不可靠。TCP 是面向连接的通讯协议,通过三次握手建立连接,通讯完成时四次挥手
优点:TCP 在数据传递时,有确认、窗口、重传、阻塞等控制机制,能保证数据正确性,较为可靠。 缺点:TCP 相对于 UDP 速度慢一点,要求系统资源较多。HTTP 协议传输的数据都是未加密的,也就是明文的,因此使用 HTTP 协议传输隐私信息非常不安 全,为了保证这些隐私数据能加密传输,于是网景公司设计了 SSL(Secure Sockets Layer)协议用于 对 HTTP 协议传输的数据进行加密,从而就诞生了 HTTPS。简单来说,HTTPS 协议是由 SSL+HTTP 协 议构建的可进行加密传输、身份认证的网络协议,要比 http 协议安全。
HTTPS 和 HTTP 的区别主要如下:
1、https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
转载地址:http://bluib.baihongyu.com/