目录
一、类方法、实例方法、静态方法区别
所有方法都属于类,在内存中只保存一份
(1)调用的时候参数不同,self,cls,什么都不传
(2)实例对象有N个,类对象只有一个
(3)类对象只能调静态和类方法,实例对象三种都可以调用
二、面向对象
self参数:哪一个对象调用的方法,就是哪一个对象的引用
print(对象的引用)返回类名和内存地址
id()返回十六进制的内存地址
__init__: 创建对象完成后会自动调用的方法,初始化类的实例属性
__del__: 对象被销毁时会自动执行的方法
__dict__:类的所有信息
__str__: 返回对象的描述信息
__repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员。
calss TestStr(Test): def __str__(self): return '[Value: %s]' % self.data >>> ts = TestStr() >>> ts >>> print ts [Value: hello, world!]
__doc__: 返回类的注释
__file__: 模块的路径
__class__: 哪个类
__module__:哪个模块
__call__:对象后面加括号,直接执行
class Entity: '''调用实体来改变实体的位置。''' def __init__(self, size, x, y): self.x, self.y = x, y self.size = size def __call__(self, x, y): '''改变实体的位置''' self.x, self.y = x, y e = Entity(1, 2, 3) // 创建实例 e(4, 5) //实例可以象函数那样执行,并传入x y值,修改对象的x y
dir():内置函数,查看对象的方法列表
身份运算符:
is用于比较两个对象的内存地址是否一致,用于判断两个变量引用对象是否为同一个
== 用来判断引用变量的值是否相等
a = [1, 2, 3]
b = [1, 2, 3]
a is b > false
a == b > True
私有属性和私有方法在类外部的访问 _类名__名称。
重写父类方法有两种情况
(1)覆盖
(2)对父类方法进行拓展
super()
三、GIL全局解释器锁
(1)每个线程执行过程中都需要先获取GIL,GIL保证同一时刻只有一个线程在执行
(2)python语言跟GIL一点关系都没有,仅仅是由于历史原因在Cpython解释器,难以移除GIL
(3)具有IO(计算密集型:多进程,读写密集型)操作可以用多线程
(4)多线程爬取比单线程效率高,因为遇到IO阻塞会自动释放GIL锁
(5)多进程可以利用多核CPU
from ctypes import *
from threading import Thread
lib = cdll.LoadLibrary("./libdead_lpoop.so")
t = Thread(target = lib.DeadLoop)
t.start()
while Ture:
pass
怎么解决GIL解释器
(1)换解释器
(2)换语言
(3)python当中执行C语言
四、继承、多态
多态:不同的子类对象调用相同的父类方法,产生不用的执行结果
Python的MRO(Method Resolution Order)方法解析顺序,在Python2.3以前是基于DFS深度深度优先搜索的,在Python2.3以后MRO的实现是基于C3算法的。C3算法最早被提出是用于lisp语言的,应用在Python中是为了解决原本基于深度优先搜索算法不满足本地优先级和单调性的问题。
本地优先级:指声明父类时的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类
单调性:如果在C的解析顺序中,A排在B的前面,那么C的所有子类里,也必须满足这个顺序
python 中的每一个类都有一个属性__mro__,返回该类中方法的搜索顺序。
class Base:
def func(self):
print('i am Base')
class Father(Base):
def func(self):
super().func()
print("i am Father")
class Mother(Base):
def func(self):
super().func()
print("i am Mother")
class Son(Father,Mother):
def func(self):
super().func() # 这个地方改成一句话了,不再显示调用两个父类的方法,而是让解释器根据MRO规则自己判断
print("i am Son")
s=Son()
s.func()
'''
i am Base
i am Mother
i am Father
i am Son
'''
五、深拷贝和浅拷贝
变量存储的是对象的地址
1、浅拷贝
(1)对于不可变类型,number, sting, tuple,浅拷贝仅仅是地址指向,不会开辟新的地址空间。
(2)对于可变数据类型,list, dict, set,浅拷贝会开辟新的地址空间(仅仅是最外层开闭了地址空间,里层还是一样的)。
(3)浅拷贝后,改变原始对象中可变类型的元素的值,会同时影响拷贝后的对象。改变原始对象中不可变类型的元素的值,不会影响拷贝后的值。
2、深拷贝
(1)递归浅拷贝
3、复制
仅传递对象的引用
1、b = a: 赋值引用,a 和 b 都指向同一个对象。
2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
六、类属性、类方法、静态方法
实例化类的时候,会给每一个实例对象分配内存空间,用来初始化实例属性,但是类中定义的实例方法不会每一个创建,只是通过self去引用。
静态方法:当方法不需要用到类的属性或者调用类的方法,也不需要实例属性和调用实例方法。
七、私有化
_x: 私有化属性或者方法,from ..import * 禁止导入, 类对象和子类可以访问
__x: 子类无法访问
__x__: 魔术方法
xx_: 避免与python关键字冲突
八、装饰器
#装饰器创建
class Goods:
@property
def size(self)
return 100
@size.setter
def size(self, value):
print()
@size.delete
def size(self):
print())
类属性创建
class Foo(object):
def get_bar(self):
print("getter...")
return 'laowang'
def set_bar(self, value):
"""必须两个参数"""
print("setter...")
return 'set value' + value
def del_bar(self):
print("deleter...")
return 'laowang'
BAR = property(get_bar, set_bar, del_bar, "description...")