列表推导list comprehension和生成器的优劣
1 .
列表推导式是将所有的值一次性加载到内存中,占用内存大
生成器是将列表推导式的[]改成(),不会将所有的值一次性加载到内存中,延迟计算,一次返回一个结果,它不会一次生成所有的结果,这对大数据量处理,非常有用,避免占用大量内存
2 .
列表推导式可以遍历任意次
生成器只能遍历一次
generator = (i for i in range(1,5))
print(next(generator))
print(next(generator))
for i in generator:
print(i)
for i in generator:
print(i)
打印结果:
1
2
3
4
list1 = [i for i in range(1,5)]
print(list1[0])
print(list1[1])
print(list1[2])
for i in list1:
print(i)
打印结果:
1
2
3
1
2
3
4
装饰器实现单例模式
class single03(object):
def __init__(self,cls):
self._cls = cls
self._instances = None;
def __call__(self,*args):
if not self._instances:
self._instances = self.cls(*args)
return self._instances
@single03
class A(object):
def __init__(self,name):
self.name = name
使用装饰器的单例和使用其他方法的单例,在后续使用中,有何区别
使用装饰器单例属性不会被覆盖。因为装饰器单例模式是直接返回之前生成的对象,并不会重新初始化对象。像new方法构建的单例模式会重新调用init方法,为实例重新初始化属性。
Import方法改变了类本身,new方法,但是只是把所有实例对象共享属性,每次产生一个新对象。算作伪单例,共享属性方法实例化了许多个相同属性。所以,装饰器方法最实用的。
手写:正则邮箱地址
import re
text = input("Please input your Email address:\n")
if re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$',text):
#if re.match(r'[0-9a-zA-Z_]{0,19}@163.com',text):
print('Email address is Right!')
else:
print('Please reset your right Email address!')
介绍下垃圾回收:引用计数/分代回收
垃圾回收:
pthon解释器对正在使用的对象保持计数,当某个对象的引用计数将为0时,垃圾收集器就可以释放该对象,获取分配的内存。当分配对象和取消分配对象的差值高于或值时垃圾回收才会启动。
分代回收:
python将所有的对象分为0,1,2,三代。所有的新建对象都是0代对象,当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象,垃圾回收启动时,一定会扫描所有的0代对象。
如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理,当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描。
引用计数(跟踪和回收垃圾):
可通过sys包中的getrefcount(引用名)来查看某个对象的引用计数
当将某个引用作为实参传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,引用计数结果比实际值多1
对于python的容器(container)对象,如:列表、字典等,其内部包含的并不是对象,而是对象的引用。
词典对象用于记录所有全局变量的引用。可通过内置函数globals()查看该词典
容器对象的引用可能会构成很复杂的拓扑结构。可通过objgraph包中的show_refs()函数来进行查看
6.objgraph包的安装(windows):pip install xdot / pip install objgraph
多进程与多线程的区别
-
进程是资源分配的基本单位,线程是CPU执行和调度的基本单位;
-
通信/同步方式:
进程:通信方式:管道,FIFO,消息队列,信号,共享内存,socket,stream流;
同步方式:PV信号量,管程
线程:
同步方式:互斥锁,递归锁,条件变量,信号量通信方式:位于同一进程的线程共享进程资源,因此线程间没有类似于进程间用于数据传递的通信方式,线程间的通信主要是用于线程同步。
-
CPU上真正执行的是线程,线程比进程轻量,其切换和调度代价比进程要小;
-
线程间对于共享的进程数据需要考虑线程安全问题,由于进程之间是隔离的,拥有独立的内存空间资源,相对比较安全,只能通过上面列出的IPC(Inter-Process Communication)进行数据传输;
-
系统有一个个进程组成,每个进程包含代码段、数据段、堆空间和栈空间,以及操作系统共享部分 ,有等待,就绪和运行三种状态;
-
一个进程可以包含多个线程,线程之间共享进程的资源(文件描述符、全局变量、堆空间等),寄存器变量和栈空间等是线程私有的;
-
操作系统中一个进程挂掉不会影响其他进程,如果一个进程中的某个线程挂掉而且OS对线程的支持是多对一模型,那么会导致当前进程挂掉;
-
如果CPU和系统支持多线程与多进程,多个进程并行执行的同时,每个进程中的线程也可以并行执行,这样才能最大限度的榨取硬件的性能;