python进阶_浅谈面向对象进阶
学了面向对象三大特性继承,多态,封装。今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数。
一、isinstance和issubclass
classFoo: pass classSon(Foo): pass s=Son() #判断一个对象是不是这个类的对象,传两个参数(对象,类) print(isinstance(s,Son)) print(isinstance(s,Foo)) #type更精准 print(type(s)isSon) print(type(s)isFoo) #判断一个类是不是另一类的子类,传两个参数(子类,父类) print(issubclass(Son,Foo)) print(issubclass(Son,object)) print(issubclass(Foo,object)) print(issubclass(int,object))
二、反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现反射的函数:hasattr,getattr,setattr,delattr
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
classFoo: def__init__(self): self.name='egon' self.age=73 deffunc(self): print(123) egg=Foo() #常用: #hasattr #getattr #print(hasattr(egg,'name')) print(getattr(egg,'name')) ifhasattr(egg,'func'):#返回bool Foo_func=getattr(egg,'func')#如果存在这个方法或者属性,就返回属性值或者方法的内存地址 #如果不存在,报错,因此要配合hasattr使用 Foo_func() #不常用: #setattr #setattr(egg,'sex','属性值') #print(egg.sex) #defshow_name(self): #print(self.name+'sb') #setattr(egg,'sh_name',show_name) #egg.sh_name(egg) #show_name(egg) #egg.sh_name() #delattr #delattr(egg,'name') #print(egg.name) #print(egg.name) #egg.func() #print(egg.__dict__) #反射 #可以用字符串的方式去访问对象的属性、调用对象的方法 反射举例1
classFoo: f=123#类变量 @classmethod defclass_method_demo(cls): print('class_method_demo') @staticmethod defstatic_method_demo(): print('static_method_demo') #ifhasattr(Foo,'f'): #print(getattr(Foo,'f')) print(hasattr(Foo,'class_method_demo')) method=getattr(Foo,'class_method_demo') method() print(hasattr(Foo,'static_method_demo')) method2=getattr(Foo,'static_method_demo') method2() #类也是对象反射举例2
importmy_module #print(hasattr(my_module,'test')) ##func_test=getattr(my_module,'test') ##func_test() #getattr(my_module,'test')() #import其他模块应用反射 frommy_moduleimporttest defdemo1(): print('demo1') importsys print(__name__)#'__main__' print(sys.modules) #'__main__':module_obj=sys.modules[__name__]#sys.modules['__main__'] #module_obj: print(module_obj) print(hasattr(module_obj,'demo1')) getattr(module_obj,'demo1')() #在本模块中应用反射 反射举例3
#对象 #类 #模块:本模块和导入的模块 defregister(): print('register') deflogin(): pass defshow_shoppinglst(): pass # print('注册,登录') ret=input('欢迎,请输入您要做的操作:') importsys print(sys.modules) #my_module=sys.modules[__name__] #ifhasattr(my_module,ret): #getattr(my_module,ret)() ifret=='注册': register() elifret=='登录': login() elifret=='shopping': show_shoppinglst() 反射举例4
deftest(): print('test')
三、类的内置函数
1、__str__和__repr__
classFoo: def__init__(self,name): self.name=name def__str__(self): return'%sobjinfoinstr'%self.name def__repr__(self): return'objinfoinrepr' f=Foo('egon') #print(f) print('%s'%f) print('%r'%f) print(repr(f))#f.__repr__() print(str(f)) #当打印一个对象的时候,如果实现了str,打印中的返回值 #当str没有被实现的时候,就会调用repr方法 #但是当你用字符串格式化的时候%s和%r会分别去调用__str__和__repr__ #不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补 #但反之不行 #用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr
2、__del__
classFoo: def__del__(self): print('执行我啦') f=Foo() print(123) print(123) print(123) #析构方法,当对象在内存中被释放时,自动触发执行。 #注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
3、item系列
__getitem__\__setitem__\__delitem__
classFoo: def__init__(self): self.name='egon' self.age=73 def__getitem__(self,item): returnself.__dict__[item] def__setitem__(self,key,value): #print(key,value) self.__dict__[key]=value def__delitem__(self,key): delself.__dict__[key] f=Foo() print(f['name']) print(f['age']) f['name']='alex' #delf['name'] print(f.name) f1=Foo() print(f==f1)
4、__new__
#classA: #def__init__(self):#有一个方法在帮你创造self #print('ininitfunction') #self.x=1 # #def__new__(cls,*args,**kwargs): #print('innewfunction') #returnobject.__new__(A,*args,**kwargs) #a=A() #b=A() #c=A() #d=A() #print(a,b,c,d) #单例模式 classSingleton: def__new__(cls,*args,**kw): ifnothasattr(cls,'_instance'): cls._instance=object.__new__(cls,*args,**kw) returncls._instance one=Singleton() two=Singleton() three=Singleton() go=Singleton() print(one,two) one.name='alex' print(two.name)
5、__call__
classFoo: def__init__(self): pass def__call__(self,*args,**kwargs): print('__call__') obj=Foo()#执行__init__ obj()#执行__call__ Foo()()#执行__init__和执行__call__ #构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()
6、__len__,__hash__
classFoo: def__len__(self): returnlen(self.__dict__) def__hash__(self): print('myhashfunc') returnhash(self.name) f=Foo() print(len(f)) f.name='egon' print(len(f)) print(hash(f))
7、__eq__
classA: def__init__(self): self.a=1 self.b=2 def__eq__(self,obj): ifself.a==obj.aandself.b==obj.b: returnTrue a=A() b=A() print(a==b) #__eq__控制着==的结果
8、内置函数实例
classFranchDeck: ranks=[str(n)forninrange(2,11)]+list('JQKA') suits=['红心','方板','梅花','黑桃'] def__init__(self): self._cards=[Card(rank,suit)forrankinFranchDeck.ranks forsuitinFranchDeck.suits] def__len__(self): returnlen(self._cards) def__getitem__(self,item): returnself._cards[item] deck=FranchDeck() print(deck[0]) fromrandomimportchoice print(choice(deck)) print(choice(deck)) 纸牌游戏
classFranchDeck: ranks=[str(n)forninrange(2,11)]+list('JQKA') suits=['红心','方板','梅花','黑桃'] def__init__(self): self._cards=[Card(rank,suit)forrankinFranchDeck.ranks forsuitinFranchDeck.suits] def__len__(self): returnlen(self._cards) def__getitem__(self,item): returnself._cards[item] def__setitem__(self,key,value): self._cards[key]=value deck=FranchDeck() print(deck[0]) fromrandomimportchoice print(choice(deck)) print(choice(deck)) fromrandomimportshuffle shuffle(deck) print(deck[:5]) 纸牌游戏2
classPerson: def__init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def__hash__(self): returnhash(self.name+self.sex) def__eq__(self,other): ifself.name==other.nameandother.sex==other.sex:returnTrue p_lst=[] foriinrange(84): p_lst.append(Person('egon',i,'male')) print(p_lst) print(set(p_lst)) #只要姓名和年龄相同就默认为一人去重 去重
以上这篇python进阶_浅谈面向对象进阶就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。