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进阶_浅谈面向对象进阶就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。