一、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深浅拷贝详解

核心点:

python的gil锁 哪个版本取消了_实例方法


python的gil锁 哪个版本取消了_类方法_02


python的gil锁 哪个版本取消了_实例方法_03

  • 当元组的数据中存在嵌套的可变类型,比如列表等,深拷贝会重新开辟地址,将元组重新成成一份

二、私有化

  • **公有变量
  • _*:单前置下划线,私有化属性或方法,导入时禁止导入,类对象和子类可以访问
  • __**:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问
  • **:双前后下划线,用户名字空间的魔法对象或属性,,不要自己发明这种名字;
  • **_:单后置下划线,用于避免与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__)

python的gil锁 哪个版本取消了_python的gil锁 哪个版本取消了_04


可以用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 直译的叫法,在程序中用来表示代码执行过程中所处的前后环境。上下文管理器中有 enterexit 两个方法,以with为例子,enter 方法会在执行 with 后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等;exit 方法会在 with 内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。