多态的概念:
一种事务具备不同的形态
例如:
比如人有多重形态:
黑人 白人 黄种人 老人 小孩
程序中的多态是指,不同对象可以相应方法,并可以有自己不同的实现方式
多态不是一种特殊的语法,它是一种状态,是一种个特性(多个不同的对象使用一种相同的方法,产生不不同的结果
也就是不同的对象使用相同的方法.
多态案例 import abc class Animal(metaclass=abc.ABCMeta): # 同一种类事务: 动物 @abc.abstractmethod def talk(self): pass class People(Animal): # 动物的形态之一: 人 def talk(self): print('你好!') class Dog(Animal): def talk(self): print('汪汪汪') a = People() B = Dog() a.talk() B.talk() class Cat(Animal): def talk(self): print('喵喵') c = Cat() c.talk()
多态的来的好处:
1.增加程序的灵活性
以不变应万变,不论对象的千变万化,使用者都是以同一个形式去调用
2.增加了程序的可扩展性,降低了使用的难度
鸭子类型:
python中崇尚鸭子类型,看起来像鸭子,叫声像鸭子那么它就是鸭子
python程序员通常根据这种标准来编写程序.如果想编写现有对象的自定义版本可以继承这个对象
也可以穿件一个外观和行为像,但是与它没有任何关系的全新对象,后者通常用于保存程序的耦合度.
isinstance :
python 中isinstance()函数,是python中的一个内置函数,是用来判断一个函数是否是另一个已知的类型,(和type类似)
判断一个对象是否是某个类的实例(对象)
isinstance(object,classinfo)
参数1 要判断的对象
参数2 要判断的类型
返回值: 如果对象的类型与参数二类型相同返回True 反之返回False
a = 2 res = isinstance(a,int) print(res) # 结果为>>>True res = isinstance(a,str) print(res) # 结果为>>>False res = isinstance(a,(int,str,list)) print(res) # 结果为True 元祖中的一是正确的的所以返回值为True
isinstance()和type()的区别 isinstance()会认为子类父类类型,考虑继承关系 type()中不会认为子类是一种父类形态,不考虑继承关系. class A: pass class B(A): pass res = isinstance(A(),A) print(res) # True print(type(A())) # <class '__main__.A'> print(isinstance(B(),A)) # True print(type(B())) # <class '__main__.B'>
issubclass:
判断一个类是否是另一类的子类
issubclass(class,classinfo)
参数:
class--->类
classinfo---> 父类
返回值:
如果class是classinfo的子类返回值True 反之为False
实例: class A: pass class B(A): pass class C: pass print(issubclass(B, A)) # 结果为True print(issubclass(C, A)) # 结果为False
__ste__方法:
__str__的方法和__int__方法类似,都是以一些特殊的方法,所以前后都有双下划线,它用来返回随想的字符串表达方式
__str__会对像被转换成字符串时,转换的结果就是这个函数的返回值,我们可以利用该函数来自定义,对象的打印格式
实例: class Person: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '这是一个person对象 name %s age %s'%(self.name,self.age) p = Person('jason',12) print(p)
__del__使用方法:
创建对象后,Python解释器默认调用__init__()方法。当删除一个对象时,Python解释器也
会默认调用一个方法,这个方法为__del__()方法。在Python中,对于开发者来说很少会直接
销毁对象(如果需要,应该使用del关键字销毁)。Python的内存管理机制能够很好的胜任这份
工作。也就是说,不管是手动调用del还是由Python自动回收都会触发__del__方法执行。
执行时机:手动删除对象时立马执行,或者是程序运行结束时也会自动执行
使用场景: 当你的对象在使用过程中,打开了不属于解释器的资源:比如文件,网络端口等
实例: class A(object): #创建初始化方法 # 创建对象后直接被调用 def __init__(self,name): print("__init__初始化方法被调用") self.name = name # 方法 当对象被删除的时候会自动调用 def __del__(self): print('__del__方法被调用了!') time.sleep(2) print('%s对象马上要被杀死了...'%self.name) dog = A('哈士奇') print('___马上杀死哈士奇') del dog get = A('苍井空') print('___马上干掉苍老师') del get >>>> 执行结果: __init__初始化方法被调用 ___马上杀死哈士奇 __del__方法被调用了! 哈士奇对象马上要被杀死了... __init__初始化方法被调用 ___马上干掉苍老师 __del__方法被调用了! 苍井空对象马上要被杀死了... >>>>
call 使用方法:
关于__call__方法,不得不要先提到一个概念,就是可调用对象(callable)
我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把
一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为
可调用对象可以用函数 callable 如果在类中实现了 __call__ 方法,那
么实例对象也将成为一个可调用对象,
什么时候调用: 在调用函数对象的时候会自动执行,也就是加括号的时候
__call__实例: class A: def __call__(self, *args, **kwargs): print('call run') print(args) print(kwargs) a = A() a(1,a = 199) >>> call run (1,) {'a': 199} >>>
__slots__节省内存:
该属性是一个类属性,用于优化对象内存占用,优化的原理,将原本不固定的属性数量变得固定。
从而达到减少内存的占用
首先我需要这世道动态语言和静态语言
python属于动态语言:可以在运行的时候修改代码
c就属于静态语言: 在编译时已经确定好了代码,在运行过程中是不被修改的
为了达到限制的目的,python允许在定义class的时候定义了一个特殊的__slots__变量来限制
class实例能添加的属性:
# __slots__实例 class Person: __slots__ = ('name','age') p = Person() p2 = Person() p.name = '隔壁老王' p.age = 89 print(sys.getsizeof(p)) print(sys.getsizeof(p2)) print(sys.getsizeof(p.name)) print(sys.getsizeof(p.age)) # print(p.__dict__) # 没有了__dict__ 所以报错了
getattr获取属性
setattr设置属性
delattr删除属性
getattr()函数用于返回一个对象属性值
getattr(object,name[,default])
object--->对象
name--->字符串,对象属性
default--->默认返回值,如果不提供这个参数,在没有对应属性时,将触发attbuteerro
getattr 用点访问属性的时候如果属性不存在的情况下执行
setattr 用点设置属性
delattr 用del 对象 .属性 删除属性时执行
这几个函数反映了python解释器是如何实现用点来访问属性
getattribute这个函数也是用来获取属性的
在获取属性时如果存在getattribute则先执行该函数,如果没有拿到属性则继续调用
getattr函数,如果拿到了则直接返回
实例: class A: def __setattr__(self, key, value): # print(key) # print(value) print('__setattr__') self.__dict__[key] = value def __delattr__(self, item): print('__delattr__') print(item) self.__dict__.pop(item) pass def __getattr__(self, item): print('__getattr__') return 345 def __getattribute__(self, item): print('__getattribute__') return super().__getattribute__(item) a = A() a.name = 'jason' # print(a.name) # # a.age = 19 del a.name print(a.name)
[]的实例:
getitem 当你用括号去获取属性时执行
setitem 当用括号去设置属性时 执行
delitem 当你用括号删除属性时执行
实例: class MyDict(dict): pass def __getattr__(self, key): return self.get(key) def __setattr__(self, key, value): self[key] = value def __delattr__(self, key): del self[item] a= MyDict() a['name'] = 'jack' print(a['name']) print(a.name) a.age = 20 print(a.age)
运算符重载
当我们在使用某个符号时,python解释器都会为这个符号定义一个含义,同时调用
对应的处理函数,当我们需要自定义对象的比较规则时,就可在子类中覆盖大于等于
等等一系列的方法。。。
案例: 原本自定义对象无法直接使用大于小于等于来进行比较,我们 可以自定义运算符来实现,让自定义对象也支持比较运算符 class Student(object): def __init__(self,name, age, height): self.name = name self.age = age self.height = height def __gt__(self, other): # 大于 print(self) print(other) print("__gt__") return self.age > other.age def __lt__(self, other): return self.name < other.name def __eq__(self, other): if self.height == other.height and self.name == other.name and self.age == other.age: return True return False s1 = Student('肉丝',20, 175) s2 = Student('杰克',20, 175) print(s1 < s2) print(s1 < s2) print(s1 == s2)
迭代器协议:
迭代器是指具有__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,100,2): print(i)
上下文管理
上下文context
这个概念术语语言学科,指的是一段话的意义,要参考当前的场景,即上下文
在python中,上下文可以理解为是一个代码区间,一个范围,比如with open
打开文件仅仅是在这个上下文中有效
上下文涉及了两个方法;
enter:进入 表示进入上下文,或者说进入某个场景
exit:推出 表示推出上下文,或者说是退出某场景
enter 函数应该有返回值,返回值是对象自己
exit函数可以有返回值,是一个bool值,用于表示一场是否被处理,仅在上下文中出现异常时用
如果为True 意味着,异常已经被处理了
False 为异常没有被处理
当执行with 语句时候会优先执行enter
当代码制行完毕后制行exit,或者是代码遇到异常会立即制行exit,并传出错误信息
包含错错误类型,错误信息。错误的追踪信息
# 实例一 class Poo: def __int__(self): print('实例化一个 对象') def __enter__(self): print('进入...') def __exit__(self, exc_type, exc_val, exc_tb): print('退出...') # return True # return False p = Poo() print(p) with p: raise ImportError print('正在制行。。。') #"""出现异常时,如果 __exit__ 返回 False(默认不写返回值时,即为False),则会重新抛出异常,让with 之外的语句逻辑来处理异常,这也是通用做法;如果返回 True,则忽略异常,不再对异常进行处理""" class MyOpen: def __init__(self,path): self.path = path def __enter__(self): self.file = open(self.path) print("进入...") return self def __exit__(self, exc_type, exc_val, exc_tb): print('退出...') self.file.close() return True # retuen False with MyOpen("a.txt")as f: # 23+'34' print(f) print(f.file.read())