1、python装饰器
1.1、装饰器的概念
装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)
1.2、装饰器的使用场景
登陆鉴权,日志打印,函数执行时长统计
def login_check(func):
def wrapper(request, *args, **kwargs):
if not request.session.get('login_status'):
return HttpResponseRedirect('/api/login/')
return func(request, *args, **kwargs)
return wrapper
@login_check
def edit_config():
pass
"""
> 1. def login_check(func): ==>将login_check函数加载到内存
> ....
> @login_check ==>此处已经在内存中将login_check这个函数执行了!;并不需要等edit_config()实例化调用
> 2. 上例@login_check内部会执行以下操作:
> 2.1 执行login_check函数,并将 @login_check 下面的 函数(edit_config) 作为login_check函数的参数,即:@login_check 等价于 login_check(edit_config)
> 2.2 内部就会去执行:
def wrapper(*args):
# 校验session...
return func(request, *args, **kwargs) # func是参数,此时 func 等于 edit_config,此处相当于edit_config(request, *args, **kwargs)
return wrapper # 返回的 wrapper,wrapper代表的是函数对象,非函数实例化对象
2.3 其实就是将原来的 edit_config 函数塞进另外一个函数中,另一个函数当中可以做一些操作;再执行edit_config
2.4 将执行完的 login_check 函数返回值(也就是 wrapper对象)将此返回值再重新赋值给新 edit_config,即:
2.5 新edit_config = def wrapper:
# 校验session...
return 原来edit_config(request, *args, **kwargs)
> 3. 也就是新edit_config()=login_check(edit_config):wrapper(request, *args, **kwargs):return edit_config(request, *args, **kwargs) 有点绕,大家看步骤细细理解。
"""
2、python迭代器
2.1、基本概念:是指该对象可以被用于for…in…循环,例如:集合,列表,元祖,字典,字符串,迭代器等,在python中如果一个对象实现了 __iter__方法,我们就称之为可迭代对象
3、python生成器
3.1、基本概念:在Python中,一边循环一边计算的机制,称为生成器:generator;同时生成器对象也是迭代器对象,所以他有迭代器的特性;例如支持for循环、next()方法…等
4、python多线程
python3可以使用threading模块实现
threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
- threading.currentThread(): 返回当前的线程变量。
- threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
- threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
# run(): 用以表示线程活动的方法
# start():启动线程活动
# join([time]): 等待至线程中止
# isAlive(): 返回线程是否活动的
# getName(): 返回线程名
# setName(): 设置线程名
import threading
import time
def sing(num):
for i in range(num):
print("sing%d" % i)
time.sleep(0.5)
def dance(num):
for i in range(num):
print("dancing%d" % i)
time.sleep(0.5)
def main():
"""创建启动线程"""
t_sing = threading.Thread(target=sing, args=(5,))
t_dance = threading.Thread(target=dance, args=(6, ))
t_sing.start()
t_dance.start()
if __name__ == '__main__':
main()
5、python垃圾回收机制
'''
python多线程详解
什么是线程?
线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。
线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所
拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
'''
'''
为什么要使用多线程?
线程在程序中是独立的、并发的执行流。与分隔的进程相比,进程中线程之间的隔离程度要小,它们共享内存、文件句柄
和其他进程应有的状态。
因为线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行过程之中拥有独立的内存单元,而多个线程共享
内存,从而极大的提升了程序的运行效率。
线程比进程具有更高的性能,这是由于同一个进程中的线程都有共性,多个线程共享一个进程的虚拟空间。线程的共享环境
包括进程代码段、进程的共有数据等,利用这些共享的数据,线程之间很容易实现通信。
操作系统在创建进程时,必须为改进程分配独立的内存空间,并分配大量的相关资源,但创建线程则简单得多。因此,使用多线程
来实现并发比使用多进程的性能高得要多。
'''
'''
总结起来,使用多线程编程具有如下几个优点:
进程之间不能共享内存,但线程之间共享内存非常容易。
操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此使用多线程来实现多任务并发执行比使用多进程的效率高
python语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了python的多线程编程。
'''
6、python深浅拷贝
浅拷贝:对于不可变数据类型(整数、字符串、浮点数、布尔型、元组)拷贝的时候新开辟地址空间,对于可变数据类型(列表、字典、集合)拷贝的是地址引用,不会开新空间
深拷贝:对于不可变数据类型(整数、字符串、浮点数、布尔型、元组)拷贝的时候新开辟地址空间,对于可变数据类型(列表、字典、集合)拷贝的时候会开辟心新的地址空间
所以,浅拷贝,当改变新对象的可变数据类型内容的时候,会改变原对象的内容;深拷贝,当改变新对象的可变数据类型内容的时候,不会改变原对象的内容
一张图解答所有疑问
7、测试流程
8、项目



