GIL全局解释器锁
- Python语言和GIL没有关系。仅仅由于历史原因Cpython虚拟机(解释器)难以移除。
- GIL:全局解释器锁。每个线程在执行的过程中都需要先获取GIL,保证统一时刻只有一条线程可以执行代码。
- 线程释放GIL锁的情况:在IO操作等可能引起线程阻塞的system call之前,可以暂时释放GIL锁,但在执行完毕后,必须重新获取GIL python3.x使用计时器(执行时间达到阀值后,当前线程释放GIL)或者python2.x tickets计时器达到100.
- python使用多进程是可以利用多喝的CPU资源的。
- 多线程爬取比单线程性能有提升,因为遇到IO堵塞会自动释放GIL锁。
解决GIL问题
- 换解释器
- 使用其他语言来执行
浅拷贝和深拷贝
浅拷贝:copy.copy()
深拷贝:copy.deepcopy()
>>> import copy
>>> a = [11, 22]
>>> b = [33, 44]
>>> c = [a, b]
>>> d = copy.copy(c)
>>> id(c)
4371981704
>>> id(d)
4371981768
>>> id(c[0])
4371204488
>>> id(d[0])
4371204488
>>>
>>> e = copy.deepcopy(c)
>>> id(e)
4371981640
>>> id(e[0])
4372002312
注意:如果copy.copy拷贝的是元组,不会进行浅拷贝,仅仅是指向,因为元组不可变类型,意味着数据不能修改,即拷贝了没意义。
>>> a = (11, 12) # 内部元素为不可变类型
>>> b = copy.deepcopy(a)
>>> id(a)
4371670664
>>> id(b)
4371670664
>>> a = [11, 22] # 内部元素是可变类型
>>> b = [33, 44]
>>> c = (a, b)
>>> d = copy.copy(c)
>>> e = copy.deepcopy(c)
>>> id(c)
4371670664
>>> id(d)
4371670664
>>> id(e)
4371980488
私有化
- xx:公有变量
- _x:前单置下划线,from somemodule import *禁止导入,类对象和子类可以访问
- __xx:双前置下划线,避免和子类中的属性命名冲突,无法在外部直接访问
- __xx__:双前后下划线,用户名字空间的魔法对象或属性。子类可以继承。
import 搜索路径
>>>import sys
>>>sys.path
['',
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
'/usr/local/lib/python3.7/site-packages']
程序执行时添加新的模块路径
>>> sys.path.insert(0,"/home/python/xxx")
>>> sys.path
['/home/python/xxx',
'',
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
'/usr/local/lib/python3.7/site-packages']
>>>
重新导入模块
import module后,不能重新导入,必须使用reload
from imp import reload
reload(模块名)
多个模块导入的注意点
注意全局共享变量问题,import xxx 含义是导入xxx这个模块的内容,并且定义了一个xxx变量来指向它。
多继承以及MRO顺序
xxx.__mro__
args kwargs的拆包
def test2(a, b, *args, **kwargs):
print("------")
print(a)
print(b)
print(args)
print(kwargs)
def test1(a, b, *args, **kwargs):
print(a)
print(b)
print(args)
print(kwargs)
# test2(a, b, args, kwargs) # 相当于test2(11, 22, (33, 44, 55, 66), {"name":"laowang", "age":18})
# test2(a, b, *args, kwargs) # 相当于test2(11, 22, 33, 44, 55, 66, {"name":"laowang", "age":18})
test2(a, b, *args, **kwargs) # 相当于test2(11, 22, 33, 44, 55, 66, name="laowang", age=18)
test1(11, 22, 33, 44, 55, 66, name="laowang", age=18)
类对象和实例对象
![](https://img.haomeiwen.com/i2317152/fe9c9378afe102ab.png)
![](https://img.haomeiwen.com/i2317152/7f4faa8b875a57e7.png)
![](https://img.haomeiwen.com/i2317152/f7e4282cba356028.png)
property属性
一种用起来像使用实例属性一样的特殊的属性,可以对应于某个方法。
![](https://img.haomeiwen.com/i2317152/faacc4218960b46d.png)
![](https://img.haomeiwen.com/i2317152/742dfcd42a80d75d.png)
![](https://img.haomeiwen.com/i2317152/7426125c8d40f52e.png)
property属性-装饰器
![](https://img.haomeiwen.com/i2317152/a12a35a2a3b1d284.png)
![](https://img.haomeiwen.com/i2317152/db1ff29272de83c1.png)
![](https://img.haomeiwen.com/i2317152/0c3fc1481db8d250.png)
![](https://img.haomeiwen.com/i2317152/53c7a916b54bf4ba.png)
![](https://img.haomeiwen.com/i2317152/40755966c89b9849.png)
私有属性
class Test(object):
def __init__(self, name):
self.__name = name
a = Test("zyx")
print(a.__dict__) #查看实例对象的属性
# 访问私有属性
print(a._Test__name)
class Test(object):
def __init__(self, name):
self.__name = name
a = Test("zyx")
print(a.__dict__) # 检查类或者实例对象的属性
print(Test.__dict__)
# 访问私有属性
print(a._Test__name)
# 魔法属性 python的类属性存在着一些具有特殊含义的属性
print(Test.__doc__) # 输出文档
print(Test.__module__) # 输出模块
print(Test.__class__) # 输出类
print(a)
print(a.__str__()) # 输出当前对象的描述 调用__str__方法
>>> nums = [x for x in range(10)]
>>> print(nums)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(nums[:3])
[0, 1, 2]
>>> nums[:3] = [11, 22, 33]
>>> print(nums)
[11, 22, 33, 3, 4, 5, 6, 7, 8, 9]
>>>
with 上下文管理器
def test1():
f = open("zyx.txt", "w")
try:
f.write("hello python")
except IOError:
pass
finally:
f.close()
def test2():
with open("zyx.txt","w") as f:
f.write("hello python")
def main():
test1()
if __name__ == '__main__':
main()
上下文管理器
任何实现了enter()和exit()方法的对象都可以称之为上下文管理器。
![](https://img.haomeiwen.com/i2317152/f1eb87f215cd2cdd.png)
![](https://img.haomeiwen.com/i2317152/a12a4d44d70a3124.png)
总结:Python提供了with语法用于简化资源操作的后续清除操作,是try/finally的替代方法,实现原理建立在上下文管理器之上。此外,Python还提供了一个contentmanager 装饰器,更进一步简化上下文管理器的实现方式。
网友评论