Polymorphism
What is polymorphic
A thing with a variety of different forms, for example, water: solid, liquid, gaseous
The official explanation: a plurality of objects of different classes can respond to the same method, different results
First emphasized polymorphism is not a special syntax, but a state, characteristic (i.e., a plurality of different objects can respond to the same method, different results), that would like to have a plurality of multiple use of the same
benefit:
Extra users, greatly reducing the difficulty of use, before writing under USB interface mouse, keyboard input polymorphism
Multi-state
Interfaces, abstract classes, duck type, could be written with multi-state code is the simplest type of duck
'' ' To manage the chickens, ducks and how we can best facilitate the management, that is to say the same sentence, they can understand that they have the same method ' '' class Chicken: DEF Bark (Self): Print ( ' gegege ' ) DEF the spawn (Self): Print ( ' the egg ... ' ) class Duck: DEF Bark (Self): Print ( ' GAGAGA ' ) DEF the spawn (Self): Print ( ' the duck ... ' ) class Goose: DEFBark (Self): Print ( ' Eee ' ) DEF the spawn (Self): Print ( ' the goose ... ' ) C = Chicken () D = Duck () G = Goose () DEF Mange (obj): obj .spawn () Mange (C) Mange (D) Mange (G) # Python everywhere in the polymorphic A = 10 B = ' 10 ' C = [10 ] Print (type (A)) Print (type (B) ) Print(type(c))
Built-in functions related oop
isinstance
Determining whether an object is an instance of a class
To determine a parameter object
To determine the type of the parameter 2
issubclass
Determining whether a class is a subclass of another class
The first parameter subclass
Two parameters is the parent class
DEF add_num (A, B) IF the isinstance (A, int) and the isinstance (B, int): return A + B return None Print (add_num (20,10 )) class Animal: DEF EAT (Self): Print ( ' animals have eat ... ' ) class pig (Animal): DEF eAT (Self): Print ( ' pigs eat something ... ' ) class Tree: DEF Light (Self): Print ( ' plant photosynthesis ... ') Pig = Pig () t = Tree () DEF Mange (obj): IF issubclass (of the type (obj), obj): obj.eat () the else : Print ( ' not an animal! ' ) Mange (Pig) Mange ( T) Print (issubclass (Tree, Object))
str
__str__ will be when the object is converted to a string, the result of this conversion is the return value of the function
Usage scenarios: We can use this function to customize the object is to print format
of the
The actual execution: immediately execute when manually delete objects, or automatically executed when the program ends
Usage scenarios: When you re-use objects, open the resource does not belong to the interpreter: such as files, network port
import sys import time 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) pass def __del__(self): print('del run') p = Person('jack',20) # del p time.sleep(. 3 ) # STR (P) Print ( ' over ' ) # del Use Case class FileTool: '' ' class file read and write operations for a simplified ' '' DEF the __init__ (Self, path): self.file = Open ( path, ' RT ' , encoding = ' UTF-8 ' ) self.a = 100 DEF the Read (Self): return self.file.read () # where you can determine a thing, certainly not use this object, so you can safely close the file DEF __del__ (Self): self.file.close () Tool = FileTool('a.txt') print(tool.read)
call
The actual execution: automatically executed when the calling object (the object that is in brackets)
class A: def __calss__(self, *args, **kwargs): print('call run') print(args) print(kwargs) a = A() a(1,a=100)
slots
This property is a class attribute for the object to optimize memory usage
Optimization of principle, not the original fixed number of attributes, become fixed
So the interpreter does not create a namespace for this object, so did the __dict__
So as to achieve the effect of reducing memory overhead
In addition, when there is a class slots, it will cause the object of this class can not add a new property
class the Person: __slots__ is = [ ' name ' ] DEF the __init__ (Self, name): the self.name = name Print (. Self the __dict__ ) P = the Person ( ' Jack ' ) # Check memory footprint # Print (sys.getsizeof (P) ) # p.age = 20 # unable to add # dict no Print (the p-. __dict__ )
getattr setattr delattr
When the access point using getattr property, if the property is not present to perform
When setting properties with the point setattr
delattr with del objects executed at the property delete property
These functions reflects the python interpreter is how to access the property by point
This function is used to get getattribute properties
在获取属性时如果存在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) # slef.__dict__.pop(item) # pass def __getattr__(self,item): print('__getattr__') return 1 def __getattribute__(self,item): print('__getattribute__') # return self.__dict__[item] return super().__getattribute__(item) a = A() # a.name = 'jack' # # print(a.name) # # del a.name # print(a.name) # print(a.xxx) # a.name = 'xxx' print(a.name) # b = A() # b.__dict__['name'] = 'jack' # print(b.name)
[ ] 的实现原理
getitem setitem delitem
任何的符号都会被解释器解释成特殊含义,例如 . [ ] ()
getitem 当你用中括号去获取属性时 执行
setitem 当你用中括号去设置属性时 执行
delitem 当你用中括号去删除属性时 执行
class A: def __getitem__(self,item): print('__getitem__') return self.__dict__[item] def __setitem__(self,key,value): print('__setitem__') self.__dict__[key] = value def __delitem__(self,key): del self.__dict__[key] print('__delitem__') a = A() # a.name = 'jack' a['name'] = 'jack' print(a['name']) del a['name'] print(a['name']) '''需求让一个对象支持 点语法来取值 也支持括号取值''' class MyDict: pass def __getattr__(self,key): return self.get(key) def __setattr__(self,key,value): self[key] = value del __delattr__(self,item): del self[item] a = MyDict() a['name'] = 'jack' print(a['name']) print(a.name) a.age = 20 print(a['age']) a.name a['name'] = 'jack' a.append(10) print(a)
运算符重载
当我们在使用某个符号时,python解释器都会为这个符号定义一个含义,同时调用对应的处理函数,当我们需要自定义对象的比较规则时,就可以在子类中覆盖 大于 等于 等一系列方法
# 原本自定义对象无法直接使用大于小于来进行比较,我们可以自定义运算符来实现,让自定义对象也支持比较运算符 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,20) stu2 = Student('rose',150,18) # stu2 = Student('jack',180,20) print(stu1 < stu2) #print(stu1 == stu2)
上述代码中,other指的是另一个参与比较的对象,大于和小于只要实现一个即可,符号如果不同,解释器会自动交换两个对象位置
迭代器协议
迭代器是指具有__iter__和__next__的对象
我们可以为对象增加这两个方法来让对象编程一个迭代器
class MyIter: '''num传入 用来指定迭代次数''' def __init__(self,num): self.num = num self.c = 0 def __iter__(self): return self def __next__(self): self.c += 1 if self.c <= self.num: return '哈哈' else: raise StopIteration for i in MyIter(10): print(i) for i in range(1,10): print(i) for i in [1,2,3,4]: pass # 实现一个自定义的range 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)
上下文管理
上下文 context
这个概念属于语言学科,指的是一段话的意义,要参考当前的场景,即上下文
例如with open 打开的文件仅在这个上下文中有效
涉及到两个方法:
enter:表示进入上下文,(进入某个场景了)
exit:表示退出上下文,(退出某个场景了)
当执行with语句时,会限制性enter,
当代码执行完毕后执行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()