多态:
多态不是指的什么语法,指的是一种状态,特性。就是多个不同的类对象可以依据同一种方法得到不同的结果。
经典的例子就是鸭子类型。
例子:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
def animal(dervice): dervice.bark() dervice.foot() class Dog: def bark(self): print('嘎嘎嘎') def foot(self): print('四条腿走') class Chicken: def bark(self): print('咯咯咯') def foot(self): print('2条腿跑') d = Dog() c = Chicken() animal(d) animal(c)
OPP内置函数:
isinstance
判断某个对象是否是某一个类的实例
isinstance(o,cls)前面是要判断的对象,后面是判断的类
issubclass
判断是否为某一个类的子类
参数一是子类,参数2是父类
__str__:
是在将对象转换成字符串类型的时候触发,转换的结果就是__str__返回的结果。
例子:
class Person: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '转换成功' p = Person('jack',18) print(str(p))
__del__:
是在手动删除对象时触发,第二就是在程序运行结束的时候执行。
因为python解释器只会回收属于其的,而有时候文件并不是。
例子:
class P: def __init__(self,name): self.name = name def __del__(self): del self.name p = P('jack') # print(p.name) del p.name print(p.name)
__call__:
是在对象实例化时执行,在调用对象时自动执行,(既对象加括号)
例子:
class Pm: def __call__(self, *args, **kwargs): print('是我在执行') # print(*args) # print(**kwargs) l = Pm() l(3333)
__slots__是一个类属性,用于优化对象内存占用,优化的原理,将原来不固定的属性数量变得固定了。这样解释器不会为这个对象创建名称空间了,也就是__dict__了。从而达到减少内存开销的结果。
另外当类中出现了slots时,将导致这个类只能拥有solts中属性,不能有新的。是一个列表套字符串
例子:
class O: __slots__ = ['name','age'] def __init__(self,name): self.name = name o = O('jack') print(o.name) o.age = 18 print(o.age)
__getattr__,__setattr__,__delattr__:
__getattr__是在获取属性时,这个属性不存在时会触发
__setattr__是在点语法设置属性时自动触发
__delattr__是在删除属性时自动触发
例子:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
class T: def __getattr__(self, item): print(11111111) # return self.get(item) def __setattr__(self, key, value): # self[key] = value print(222222) def __delattr__(self, item): # del self[item] print(3333333) t = T() # print(t.name) #触发__getattr__ t.name = 10 # 触发__setattr__ del t.name #触发__delattr__
[]实现
__getitem__,__setitem__,__delitem__
__getitem__是使用中括号获取值时执行
__setitem__是使用中括号修改值时执行
__delitem__是使用中括号删值时触发
例子:
class U: def __getitem__(self, item): print(1111) # return self[item] def __setitem__(self, key, value): print(22222222) def __delitem__(self, key): print(3333333) u = U() u['name'] = 'jack' print(u['name']) del u['name']
运算符重载:
原本对象之间不能用运算符来比较大小,而我们现在可以用自定义的运算符来比较对象与对象之间的大小。
__gt__是比较大于
__lt__是比较小于
__eq__是比较是否等于
里面的other是要比较的对象
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
class Student(object): def __init__(self,name,height,age): self.name = name self.height = height self.age = age def __gt__(self, other): # print(self) # print(other) # print("__gt__") return self.height > other.height def __lt__(self, other): return self.height < other.height def __eq__(self, other): if self.name == other.name and self.age == other.age and self.height == other.height: return True return False stu1 = Student("jack",180,28) stu2 = Student("jack",180,28) # print(stu1 < stu2) print(stu1 == stu2)
迭代器协议
迭代器指的是内置有__iter__和__next__方法的对象
我们可以为对象增加这两个方法让其变成一个迭代器
例子:
class MyRange: def __init__(self,start,end,step): self.start = start self.end = end self.step = step def __iter__(self): return self def __next__(self): a = self.start self.start += self.step if a < self.end: return a else: raise StopIteration for i in MyRange(1,10,2): print(i)
上下文处理
这个概念属于语言学科,指的是一段话的意思,要参考当前的场景,即上下文。
在python中指的是,一个范围,你出了这个场景就没有作用了。
涉及到了2个方法
enter进入场景
exit退出场景
当执行with语句时,会先执行enter语句,等代码执行完毕后执行exit方法,如果遇到异常会直接执行exit方法,exit里面包含错误的类型,错误的信息,错误的追踪信息。
注意:
enter:函数应该返回对象自己
exit函数可以有返回值,是一个bool类型,用于表示异常是否被处理,仅在上下文中有效处理将没有用了
如果为True表示已经被处理了,false就是没有被处理。
例子:
class MyOpen(object): def __init__(self,path): self.path = path def __enter__(self): self.file = open(self.path) print("enter.....") return self def __exit__(self, exc_type, exc_val, exc_tb): print("exit...") # print(exc_type,exc_val,exc_tb) self.file.close() return True with MyOpen("a.txt") as m: # print(m) # print(m.file.read()) "123"+1 # m.file.read()