1.8.1. 常用¶
学了Python你能做什么¶
数据分析挖掘:
利用Python基础库,如Numpy、Pandas与可视化Matplotlib等等库实现对数据分析挖掘 a. Kaggle入门:泰坦尼克号幸存者 b. 电影人物关系提取 c. 出租车与网约车调度 d. 租房问题 e. NBA比赛结果预测
机器学习与深度学习:
利用机器学习算法和深度学习算法解决问题 a. 人脸识别 b. K-近邻算法实现手写数字识别 c. 中文错别字高亮系统 d. 街边字符识别
网络开发:
利用Python网络框架,如Flask、Django及异步框架Toronto等等实现网站开发 a. Django搭建个人博客 b. Flask实现简易聊天室 c. 信息管理系统
爬虫:
利用Python基础库,如Request库及相应提取文本方式获取目标信息 a. 微信好友信息批量获取 b. 微博热搜 c. 爬取知乎图片 d. 爬取天气预报 e. 网易云音乐
在 Python 中,如果您修改一个类实例的基本属性值,即使属性的值改变了,实例对象的地址并不会改变。这是因为对象的地址是由其 id 决定的,而 id 是对象的唯一标识符,不会因为属性值的改变而改变。
问题¶
问题一¶
问题:在a模块有一个变量a1, 在b模块使用 from a import a1.在a模块有个线程定时修改a1的值,b模块中a1的值是否跟着改变
from a import a1
在b.py中导入的是a1的当前值,而不是对a1的引用。导入时,b.py中的a1只是一个独立的副本,不会随a.py中的a1变化而变化。如果你希望在b.py中能够实时获取a.py中a1的最新值,可以通过直接导入模块
b模块中a1的值是否跟着改变取决于Python的引用机制:
Python 引用机制¶
Python 是一种动态语言,使用引用机制来管理对象。这意味着变量实际上存储对对象的引用,而不是对象的本身。当您从一个模块导入一个变量时,您实际上是在导入对该模块中对象的引用的副本。
在单线程情况下,如果a模块中的线程修改了a1的值,那么b模块中导入的a1变量也会引用修改后的值。这是因为Python 引用机制是共享的。当a1的值被修改时,所有引用该值的变量都会看到修改后的值。
在多线程情况下,情况会变得更加复杂。由于Python线程是隔离的,因此a模块中的线程修改a1的值不会立即影响b模块中导入的a1变量。这是因为b模块中的a1变量引用的是a模块中线程修改之前的值。
内存模型¶
对象:在 Python 中,一切皆为对象。每个对象都有自己的类型、值和唯一的标识符(即内存地址)。对象的类型和值可以通过 type() 和 id() 函数获取。
引用计数:Python 使用引用计数来管理对象的内存。每个对象都有一个引用计数器,记录着对该对象的引用数量。当引用计数减少到 0 时,表示没有任何引用指向该对象,Python 将自动释放该对象的内存。引用计数可以通过 sys.getrefcount() 函数来获取。
垃圾回收:除了引用计数之外,Python 还使用垃圾回收机制来处理循环引用等情况。Python 的垃圾回收机制主要通过标记-清除(Mark and Sweep)算法来实现,定期检查并清理不再被引用的对象。垃圾回收器可以通过 gc 模块来手动控制或调整。
内存管理:Python 解释器使用内存池来管理小型对象的内存分配和释放,以减少内存碎片和提高性能。内存池将预先分配一定大小的内存块,当对象小于一定大小时,直接从内存池中分配内存。内存池可以通过 gc 模块来手动控制或调整。
GIL全局锁¶
python始于1991年,创立初期对运算的要求不高,为了解决多线程共享内存的数据安全问题,引入了GIL锁,全称为Global Interpreter Lock,也就是全局解释器锁。
GIL规定,在一个进程中每次只能有一个线程在运行。这个GIL锁相当于是线程运行的资格证,某个线程想要运行,首先要获得GIL锁,然后遇到IO或者超时的时候释放GIL锁,给其余的线程去竞争,竞争成功的线程获得GIL锁得到下一次运行的机会。
GIL是个历史遗留问题,过去的版本迭代都是以GIL为基础来的,想要去除GIL还真不是一件容易的事,所以我们要做好和GIL长期面对的准备。
需要注意的是,GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。而Python解释器,并不是只有CPython,除它之外,还有PyPy,Psyco,JPython,IronPython等。
在绝大多数情况下,我们通常都认为 Python == CPython,所以也就默许了Python具有GIL锁这个事。
多进程模型¶
每个进程有自己的内存空间:在Python的多进程中,每个进程都有自己的内存空间,这意味着你在一个进程中修改的全局变量不会影响到其他进程中的全局变量。
初始化全局变量:如果你在父进程中定义了一个全局变量,并希望在子进程中访问或修改它,你需要确保这个变量在子进程中是可访问的。但是,由于子进程有自己的内存空间,它们看到的只是这个全局变量的一个副本。
共享内存:如果你需要在多个进程之间共享数据(例如全局变量),你可以使用multiprocessing模块提供的各种同步原语,如Queue、Pipe、Value、Array、Manager等。
多进程中共享全局变量¶
使用进程间通信(IPC)机制:可以使用诸如管道、消息队列、共享内存等IPC机制来在进程之间传递数据。这些方法需要借助于 multiprocessing 模块中的类(如 Pipe、Queue、Manager 等)来实现数据共享。
使用共享内存:multiprocessing 模块提供了 Value 和 Array 类来创建共享内存,这使得多个进程可以访问和修改同一块内存区域。
interpreters¶
Cpython
Jython: 底层就是JVM
ironpython: 底层是.Net
pypy
micropython
相关资料¶
龙珠计划 Python 基础知识大全: https://tianchi.aliyun.com/specials/promotion/aicamppython
推荐书¶
《Python源码剖析:深度探索动态语言核心技术》