python基础之面向对象高级
一.isinstance(obj,cls)和issubclass(sub,super)
class Foo: pass obj=Foo() print(isinstance(obj,Foo)) # 推荐使用该函数来判断一个函数的类型 判断一个对象是否是一个类的实例 print(type(obj) is Foo)#(之前的方法,以后都用isinstance) # print(isinstance('abc',str))#判断abc是否为字符串 # print(isinstance(123,int))#判断123是否为数字整型 print(issubclass(Foo,object))
二.反射
2.1什么是反射
通过字符串来操作类与对象的属性,这种操作称为反射
class People: country="China" def __init__(self,name): self.name=name def tell(self): print('%s is aaa' %self.name) obj=People('egon')
2.2hasattr的使用(判断类里面是否有一个属性)
print(hasattr(People,'country'))#判断这个类里面有没有属性 print('country' in People.__dict__)#这是他的原理 print(hasattr(obj,'name')) print(hasattr(obj,'country')) print(hasattr(obj,'tell'))
2.3getattr的使用(拿到对象的属性,没有就用默认值) #不报错就用默认值
x=getattr(People,'country1',None) print(x) f=getattr(obj,'tell',None)#obj.tell print(f == obj.tell) f() obj.tell()
2.4setattr的使用 #设置属性
People.x=111 setattr(People,'x',111) print(People.x) obj.age=18 setattr(obj,"age",18) print(obj.__dict__)
2.5delattr的使用
del People.country delattr(People,"country") print(People.__dict__) del obj.name delattr(obj,"name") print(obj.__dict__)#去名称空间看一下
反射的应用
需求:用户输入cmd能反射到真正的功能上
class Foo: def run(self): while True: cmd=input('cmd>>: ').strip() # print('%s run...' %cmd) if hasattr(self,cmd): func=getattr(self,cmd) func() def download(self): print('download....') def upload(self): print('upload...') obj=Foo() obj.run()
三.面向对象class内部的一些内置的方法
__str__
class Foo: pass obj=Foo() print(obj) #<__main__.Foo object at 0x0000021AD564EB38> l=list([1,2,3]) print(l)#[1, 2, 3](经过处理)
class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def __str__(self): #打印的时候自动触发 # print('========>') return '<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex) obj=People('egon',18,'male') print(obj) #print(obj.__str__()) #本身就在打印他的返回值 # l=list([1,2,3]) # print(l) #这里其实是打印他的返回值
__del__
import time class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def __del__(self): # 在对象被删除的条件下,自动执行 print('__del__') obj=People('egon',18,'male') del obj #obj.__del__() time.sleep(5)
# class Mysql: # def __init__(self,ip,port): # self.ip=ip # self.port=port # self.conn=connect(ip,port) # 申请系统资源 # # def __del__(self): # self.conn.close() # # obj=Mysql('1.1.1.1',3306) # 应用程序结束了obj对应的值会被回收,问题是系统资源不会被回收 # 删除obj之前保证把系统资源回收掉 class MyOpen: def __init__(self,filepath,mode="r",encoding="utf-8"): self.filepath=filepath self.mode=mode self.encoding=encoding self.fobj=open(filepath,mode=mode,encoding=encoding) def __str__(self): msg=""" filepath:%s mode:%s encoding:%s """ %(self.filepath,self.mode,self.encoding) return msg def __del__(self): self.fobj.close() # f=open('a.txt',mode='r',encoding='utf-8') f=MyOpen('aaa.py',mode='r',encoding='utf-8') # print(f.filepath,f.mode,f.encoding) # print(f) # print(f.fobj) res=f.fobj.read() print(res) # del通常回收系统资源
exec的用法
exec的作用
字符串内放一堆代码,exec是用来运行字符串内的代码的
运行字符串代码产生的名字都会放到名称空间里面去
# code=""" # global x # x=0 # y=2 # """ # global_dic={'x':100000} #全局名称空间 # local_dic={} #局部名称空间 # exec(code,global_dic,local_dic) # # print(global_dic) # print(local_dic) code=""" x=1 y=2 def f1(self,a,b): pass """ local_dic={} exec(code,{},local_dic) print(local_dic)
四.你好
pass
五.你好
pass
六.你好你好
pass
七.metaclass(元类)
八.单例模式
单例模式
一种设计模式(套路)
单个实例
一个类如果只有一个实例 那么该类称之为单例(调用多少次类的都是一个对象)
目的:为的是节省内存空间
# settings IP='1.1.1.1' PORT=3306
import settings class MySQL: __instance=None def __init__(self,ip,port): self.ip=ip self.port=port @classmethod def singleton(cls): if not cls.__instance: obj=cls(settings.IP, settings.PORT) cls.__instance=obj return cls.__instance obj4=MySQL.singleton() obj5=MySQL.singleton() obj6=MySQL.singleton() print(obj4,obj5,obj6)#三个内存地址一致 print(obj4 is obj5 is obj6)