猴子补丁,内置函数,垃圾回收机制,进程

本文介绍了Python中的猴子补丁技术,包括运行时动态替换和增加模块方法,并提醒使用时需谨慎。接着详细讲解了内置函数,如`callable()`、`enumerate()`等。深入探讨了垃圾回收机制,解释了其原理、必要性及引用计数问题。最后简要概述了进程的概念,强调了操作系统在空间和时间上的复用策略。
摘要由CSDN通过智能技术生成

一.猴子补丁

属性在运行时的动态替换,叫做猴子补丁(Monkey Patch)

猴子补丁的用法:

1、运行时动态替换模块的方法

很多代码用到 import json,后来发现ujson性能更高,如果觉得把每个文件的import json 改成 import ujson as json成本较高,或者说想测试一下用ujson替换json是否符合预期,只需要在入口加上:

# 首先在cmd输入pip3 innstall ujson安装这个第三方模块
import json
import ujson  # pip3 install ujson

def monkey_patch():
	json.__name__=ujson.__name__
	json.dumps=ujson.dummps
	json.loads=ujson.loads
monkey_patch()

2.运行时动态增加模块的方法

总结:猴子补丁虽然能够带来一些便利,但也会搞乱代码,谨慎使用

二.内置函数

callable():括号内的对象是否是可调用的

class Foo:
    pass
print(callable(Foo))  # True

chr():返回括号内整数对应的 ASCII 字符
ord():返回括号内参数对应的十进制整数(参照ASCII表)

print(chr(67))  # C
print(ord("C"))  # 67

divmod(m,n):返回m/n的商和余数

print(divmod(10,3))  # (3, 1)

enumerate():将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中.

l={'k1':111,'k2':2222}
for i,item in enumerate(l):
    print(i,item)
'''
0 k1
1 k2
'''

frozenset:冰冻集合

s1=set({1,2,3})
s1=frozenset({1,2,3})
s1.add(4)
print(s1)  # AttributeError: 'frozenset' object has no attribute 'add'

globals():以字典类型返回当前位置的全部全局变量
locals():以字典类型返回当前位置的全部局部变量

def func():
    x=111
    print(globals())
    print(locals())

func()

'''
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002926AA20940>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/A作业/day35/02 内置函数.py', '__cached__': None, 'func': <function func at 0x000002926AD85040>}

{'x': 111}
'''

pow(x,y,z):返回x**y%z的结果

print(pow(10,2,3))  # 10 ** 2 % 3 ==> 1

slice:制定切片规则

l1 = [1, 2, 3, 4, 5, 6]
l2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
s = slice(0, 4, 2)
print(l1[s])  # [1, 3]
print(l2[s])  # [1, 3]

zip():
将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

x = "hello"
y = [111, 222, 333]
res=zip(x,y)
print(list(res))  # [('h', 111), ('e', 222), ('l', 333)]

import:用于动态加载类和函数
如果一个模块经常变化就可以使用 import() 来动态载入

m=__import__("time")
m.sleep(10)

三.垃圾回收机制

1.什么是垃圾回收机制?

垃圾回收机制(简称GC)是Python解释器自带一种机,专门用来回收不可用的变量值所占用的内存空间

2.为什么要用垃圾回收机制?

程序运行过程中会申请大量的内存空间,而对于一些无用的内存空间如果不及时清理的话会导致内存溢出,导致程序崩溃,python解释器自带垃圾回收机制来管理内存

3.储备知识

堆区与栈区

在定义变量时,变量名与变量值都是需要存储的,分别对应内存中的两块区域:堆区与栈区。

1、变量名与值内存地址的关联关系存放于栈区

2、变量值存放于堆区,内存管理回收的则是堆区的内容,

直接引用与间接引用

直接引用指的是从栈区出发直接引用到的内存地址。

​ 间接引用指的是从栈区出发引用到堆区后,再通过进一步引用才能到达的内存地址。

l2 = [20, 30]  # 列表本身被变量名l2直接引用,包含的元素被列表间接引用
x = 10  # 值10被变量名x直接引用
l1 = [x, l2]  # 列表本身被变量名l1直接引用,包含的元素被列表间接引用

在这里插入图片描述

4.垃圾回收机制原理

垃圾回收机制的核心:引用计数

引用计数:变量值被变量名引用的次数

一个变量值的引用计数为0,才会被当做垃圾回收

引用计数的问题:

循环引用(交叉引用)==>内存泄露

循环引用会导致:值不再被任何名字关联,但是值的引用计数并不会为0,应该被回收但不能被回收

l1=['xxx']
l2=['yyy']
l1.append(l2)
l2.append(l1)
print(l1)  # ['xxx', ['yyy', [...]]]
print(l2)  # ['yyy', ['xxx', [...]]]

解决方案:标记清除
标记/清除算法的做法是当应用程序可用的内存空间被耗尽的时,就会停止整个程序,然后进行两项工作,第一项则是标记,第二项则是清除

#1、标记
具体地:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),
然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,
其余的均为非存活对象,应该被清除。
#2、清除
清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。
效率问题

基于引用计数的回收机制,每次回收内存,都需要把所有对象的引用计数都遍历一遍,这是非常消耗时间的,于是引入了分代回收来提高回收效率

解决方案:分代回收

分代回收的核心思想是:在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低.

分代指的是根据存活时间来为变量划分不同等级(也就是不同的代)

四.进程

程序:就是一堆代码文件
进程:

进程是一个抽象的概念
进程指的是程序的运行过程
进程是操作系统最核心的概念

操作系统

操作系统就是一个协调、管理和控制计算机硬件资源和软件资源的控制程序

操作系统的作用

1.隐藏丑陋复杂的硬件接口,提供良好的抽象接口
2.管理,调度进程,并且将多个进程对硬件的竞争变得有序

多道技术

内存中同时存入多道(多个)程序,cpu从一个进程快速切换到另外一个,使每个进程各自运行几十或几百毫秒,这样,虽然在某一个瞬间,一个cpu只能执行一个任务,但在1秒内,cpu却可以运行多个进程,这就给人产生了并行的错觉,即伪并发,以此来区分多处理器操作系统的真正硬件并行(多个cpu共享同一个物理内存)

1.产生背景:针对单核,实现并发
ps:
现在的主机一般是多核,那么每个核都会利用多道技术
有4个cpu,运行于cpu1的某个程序遇到io阻塞,会等到io结束再重新调度,会被调度到4个
cpu中的任意一个,具体由操作系统调度算法决定。

2.空间上的复用:如内存中同时有多道程序
3.时间上的复用:复用一个cpu的时间片
   强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,这样才能保证下次切换回来时,能基于上次切走的位置继续运行

空间上的复用:复用内存的空间

1.多道/个程序的代码都存入内存
2.内存空间是物理隔离的

时间上的复用:复用CPU的时间:

CPU的切换:
	1.任务的运行遇到io阻塞-->提高效率
	2.任务占用CPU时间过长-->(虽效率低,但可实现并发)

如果我们的核心目标是想让多个任务并发起来:那么无论是遇到IO还是没有遇到IO都应该让cpu在多个任务之间切换起来

如果我们的核心目标是想让多个任务的运行效率提升:我们应该只控制一个任务在遇到IO情况下切换到另外一个任务

小知识:

串行:一个运行完毕再运行下一个
并行:多个进程是真正意义上一起运行
并发:看起来是同时运行的,本质上还是一个个的运行

参考博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值