laohyx 2020-04-06
魔法方法
__repr__方法,返回对象的内存地址
class student: def __repr__(self): stu=student() print(stu) #返回对象内存地址,类中没有__repr__方法。 print(stu.__repr__()) #返回对象内存地址,类中有__repr__方法
__del__方法将类实例化后,如果没有其他操作,会执行该方法。
class student(): def __init__(self,name): self.name=name def __del__(self): print(‘del方法被调用‘) stu=student(‘张三‘,24) #初始化实例后,没有其他操作会执行del方法 del stu #删除对象,执行del方法 print(‘--------‘) #删除对象后,执行该语句。 #Python提供自动引用计数器,如果发现引用不为0,则不会执行del方法 a=stu del stu #这种情况,将stu赋给a,删除stu,先执行下一句,再删除对象 print(‘------------‘)
__new__方法,创建一个对象实例
class student: def __new__(cls,*args,**kwargs): print(‘执行new方法‘) return object.__new__(cls) #返回一个传递到init方法的实例对象 def __init(self): #self属性就是从new方法中传递过来 print(‘执行init方法‘) stu=student() #初始化实例
使用new方法可以完成一些类型转换的操作
class newInt(int): #类型转换的函数 def __new__(cls,value): return int.__new__(cls,abs(value)) #完成类型转换 a=newInt(-4.89) #使用该方法创建类 print(a) #输出a后为4
单例模式创建对象,在一次创建对象时完成,以后,每次创建的对象依然是第一次创建的对象。
class student: __isinstance=False def __new__(cls): #创建对象 if not __isinstance: cls.__isinstance=object.__new__(cls) return cls.__isinstance #返回第一个创建的对象 def __init__(self,name): self.name=name s1=student(‘张三‘) s2=student(‘李四‘) print(s1) #返回两个对象的内存地址相同,说明创建的是单例对象 print(s2)
dir(对象或类)方法。
__dir__()方法。显示对象的所有属性,包括一些私有属性。_student__age即是通过该方法显示的私有属性。student为类名。age为私有属性名。
__dict__方法,作用于对象时,会查看该对象的所有属性和值。作用于类时,会查看类的所有方法和共享属性。
使用__dict__方法可动态设置对象中没有的属性。
class stu: def __init__(self,name): self.name=name s=stu(‘张三‘) print(s.__dict__) #查看s的所有属性 s.__dict[‘id‘]=89 #设置对象s的属性id print(s.id) #设置属性后,再查看属性
__getattribute__方法在对象访问任意属性时自动调用。
class student(): #定义类 def __init__(self,name,age): self.name=name self.age=age def __getattribute(self,item): #重写魔法方法 try: return super().__getattribute_(item) #返回一个属性 except Exception as e: print(‘异常类型是‘,e) return ‘default‘ #对对象中不存在的属性返回一个默认值 stu=student(‘张三‘,24) stu.name #访问对象属性就会调用__getattribute__方法 stu.age print(stu.name) #输出属性名称会使用__getattribute__方法中的返回值 print(stu.age) stu.xxx #xxx属性不存在于stu对象中,使用异常处理机制依然能够处理,返回默认值
__getattr__方法适用于对象中没有的属性。如果使用__getattribute__方法获取没有定义的属性,且没有进行一场处理时,就会触发这个方法。
__setattr__方法用来设置对象中没有设置的属性。
class student(): def __init__(self,name): self.name=name def __setattr__(self,key,value): #定义没有设置的属性 if key==‘age‘: #设置年龄属性 if value<18: raise Exception(‘年龄属性应该大于18‘) else: self.__dict__[key]=value else: self.__dict__[key]=value def __delattr__(self,item): pass stu=student(‘张三‘) stu.age=19 #设置年龄属性为19,调用__setattr__方法 print(stu.age) #输出年龄属性19 del stu.age #删除年龄属性,调用__detattr__方法
反射。根据用户的输入来动态执行对象的各种方法。提高了程序的灵活性。
class dog(): def __init__(self,name): self.name=name def eat(self): print(‘{}正在吃‘.format(self.name)) def sleep(self): print(‘{}正在睡‘.format(self.name)) d=dog(‘二哈‘) choice=input(‘请输入选择‘) #根据用户输入执行操作 if hasattr(d,choice): try: func=getattr(d,choice) #根据输入返回输入对应的方法 func() #执行这个方法 except Exception as e: print(getattr(d,choice)) #如果输入的是属性名称,输出属性值 else: print(‘您的输入有误‘)
使用反射可以动态添加对象方法和属性
class dog(): def __init__(self,name): self.name=name def eat(self): print(‘{}正在吃‘.format(self.name)) def sleep(self): print(‘{}正在睡‘.format(self.name)) d=dog(‘二哈‘) attr=input(‘请输入属性名‘) value=input(‘请输入属性值‘) if value.isdigit(): setattr(d,attr,int(value)) else: setattr(d,attr,value) #动态定义属性值 if hasattr(d,attr): #判断增加属性后,是否出现 print(getattr(d,attr)) #输出新增的属性值 def talk(): print(‘二哈汪汪汪...‘) method=input(‘请输入新增的方法名‘) setattr(d,method,talk) #将新定义的方法增加到对象中 getattr(d,attr)() #执行新增的方法