一、GIL锁
- GIL锁和Python没有关系,仅仅是由于历史原因,在Cpython虚拟机(解释器),难以移除GIL;
- GIL:全局解释器锁,每个线程在执行过程中,都需要先获取GIL解释器锁,保证同一时刻只有一个线程可以执行代码;
- 线程释放GIL锁的情况,在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但是在执行代码之后,必须重新获取GIL,python3.x使用计时器(执行时间超过阈值后,当前线程释放GIL);
- Python使用多进程是可以利用多核的CPU资源的;
- 多线程爬取比单线程性能有所提升,因为遇到IO阻塞就自动释放GIL锁。
CPU使用率 | |
---|---|
多进程死循环 | 多个CPU使用率均为100% |
多线程死循环 | 多个CPU使用率加起来为100% |
- 计算密集型程序,需要用多进程;
- IO密集型程序,可以用线程或者协程
二、深浅拷贝
核心点:
- 当元组的数据中存在嵌套的可变类型,比如列表等,深拷贝会重新开辟地址,将元组重新成成一份
二、私有化
- **公有变量
- _*:单前置下划线,私有化属性或方法,导入时禁止导入,类对象和子类可以访问
- __**:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问
- **:双前后下划线,用户名字空间的魔法对象或属性,,不要自己发明这种名字;
- **_:单后置下划线,用于避免与Python关键词冲突。
三、其他:
1、实例方法、类方法、静态方法:
class Foo(object):
def __init__(self, name):
self.name = name # 实例属性
def ord_func(self): # 实例方法
""" 定义实例方法,至少有一个self参数 """
# print(self.name)
print('实例方法')
@classmethod
def class_func(cls): # 类方法
""" 定义类方法,至少有一个cls参数 """
print('类方法')
@staticmethod # 静态方法
def static_func():
""" 定义静态方法 ,无默认参数"""
print('静态方法')
# 创建一个实例对象
f = Foo("中国")
# 实例对象调用实例方法 实例对象.实例方法
f.ord_func()
# 实例对象调用类方法
f.class_func()
# 实例对象调用静态方法
f.static_func()
print('*'*50) # 分割线
# 类调用实例方法,要把实例对象传进去
Foo.ord_func(f)
# 类调用类方法 类名.类方法
Foo.class_func()
# 类调用静态方法 类名.静态方法
'''
实例方法、静态方法和类方法
方法包括:实例方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
实例对象可以调用实例方法、类方法、静态方法
类可以调用实例方法、类方法、静态方法
实例方法:由对象调用;至少一个self参数;执行实例方法时,自动将调用该方法的对象赋值给self;
类方法:至少一个cls参数;执行类方法时,自动将调用该方法的类赋值给cls;
静态方法:无默认参数;
对比
相同点:对于所有的方法而言,均属于类,所以在内存中也只保存一份
不同点:方法调用者不同、调用方法时自动传入的参数不同。
'''
2、property属性
- 不用传参数,且有固定的返回值时用
(1)创建方式一:
class Foo():
def func(self):
pass
# 定义property属性
@property
def prop(self): # 仅有一个self参数
print("1")
return 1 # 必须返回一个值
foo=Foo()
foo.func()
foo.prop # 调用property属性
(2)新式类:具有三种@property装饰器,可以设置setter和getter方法
class Foo(object):
# 定义property属性
@property
def prop(self):
return 1
@prop.setter # 给属性设置值
def prop(self,value):
print("prop.setter")
@prop.deleter
def prop(self):
print("prop.deleter")
return 1
foo=Foo()
foo.prop # 自动执行property修饰的prop方法,并获取方法的返回值
foo.prop=123 # 自动执行prop.setter修饰的prop方法,并将123赋值给方法的参数
del foo.prop # 删除值时,自动执行prop.deleter修饰的prop方法
(3)使用类属性,创建property属性,可以设置setter和getter方法
class foo():
def __init__(self):
self.__price = 5000
def get_price(self):
print("取到属性值")
return self.__price
def set_price(self,value):
print("修改属性名")
try:
self.__price=int(value)
except:
print("修改错误")
def del_price(self):
print("删除属性值")
price = property(get_price,set_price,del_price,'使用类属性定义property')
f = foo()
print(f.price)
f.price=2550
print(f.price)
print(foo.price.__doc__)
(4)总结
property属性;
a.一种用起来像实例属性一样的特殊属性,可以对应于某些方法,property的本质还是方法
1.property属性的定义和调用要注意几点:
1.定义时,在实例方法的基础上添加@property装饰器,
2.并且方法只有一个self参数
3.调用时无需括号
2.property的好处:
将一个属性的操作通过property封装起来,区别于实例方法,但其本质也是方法,
调用者用起来就跟操作普通属性一样,十分简洁
3.property有两种方式来定义property属性:
1.使用装饰器的方式定义property属性:
-@property:取得属性值,修饰的方法有且只有一个self参数;
-@方法名.setter:设置属性值,修饰的方法,只能传一个参数
-@方法名.deleter:删除属性的方法有且只有一个self参数
注意:这种方式用起来很简洁,但要注意其中的调用原理,他是通过类对象调用
来取得属性值,然后传递给setter设置属性值,在这部分你还可以做一些身份验证
确保数据安全,删除很少使用这种方法
2.通过类属性方式定义property属性
property()这个方法里有四个参数:
def __init__(self, fget=None, fset=None, fdel=None, doc=None)
第一个参数是方法名:获取属性值
第二个参数是方法名;设置属性值
第三个参数是方法名;删除属性值
第四个参数是字符串;描述该属性的信息,通过类名.属性名.__doc__调用
3、名字重整:
- 私有属性不可以使用类对象直接调用,是因为定义私有属性时,python将属性名称修改了(名字重整)
class Test():
def __init__(self,name):
self.__name=name
a=Test("wu")
# a.__name # 不可以调用__name
print(a.__dict__)
可以用a._Test__name取值,取出来为“wu”
4、魔法属性
- 一些含有特殊含义的属性
常用的魔法属性:
__doc__ 查看类的描述信息
格式:类.__doc __
__class__ 显示当前对象的类是谁
格式:对象.__class __
__module__ 显示当前操作的对象所在的模块
格式:对象.__module __
__new__ 创建对象时为对象分配空间,在初始化方法__init__之前被调用
格式:def __new __ ():
__init__ 初始化方法
格式:def __init __ ():
构造方法:new 和__init__的组合
__del__当对象在内存中释放时自动执行
__call__ 对象() 或类()() 触发执行__call__ 方法
__dict__ 显示类或对象中的所有属性
__str__获取对象的描述时,默认输出该方法的返回值(字符串) print或"%d"% 变量名
__getitem__ 获取
__setitem__ 设置
__delitem__ 删除
用于索引操作,如字典的使用
5、with、上下文管理器
def m1():
f=open("test.txt","w")
f.write("python练习")
f.close()
def m2():
f=open("test.txt","w")
try:
f.write("python练习")
except IOError:
print("oops error")
finally:
f.close()
def m3():
with open("test.txt","w") as f:
f.write("python练习")
- m1()在文件写入时,出现异常,回导致文件不会被关闭,m2()可以解决这个问题
- 上下文管理器:ContextManager ,上下文是 context 直译的叫法,在程序中用来表示代码执行过程中所处的前后环境。上下文管理器中有 enter 和 exit 两个方法,以with为例子,enter 方法会在执行 with 后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等;exit 方法会在 with 内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。