一 、內置函數補充 1.isinstance函數: isinstance(obj,cls)檢查obj是不是類 cls 的對象 使用該函數來判斷一個函數的類型 2. issubclass(sub, super)檢查sub類是不是 super 類的派生類 class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo)2、反射 經過字符串來操做類與對象的屬性,這種操做稱爲反射 class People: country="China" def __init__(self,name): self.name=name def tell(self): print('%s is aaa' %self.name) obj=People('egon') 一、hasattr #檢測是否含有某屬性 print(hasattr(obj,'name')) print(hasattr(obj,'country')) print(hasattr(obj,'tell')) 二、getattr #獲取對應的屬性 f=getattr(obj,'tell',None) # None爲沒有對應屬性是的默認返回值 print(f == obj.tell) f() obj.tell() 三、setattr #設置屬性等同修改操做 obj.age=18 setattr(obj,"age",18) print(obj.__dict__) 四、delattr #刪除屬性 del obj.name delattr(obj,"name") print(obj.__dict__)3、__str__方法、__del__方法 和 __call__方法 1. __str__是系統默認函數,在打印對象時自動觸發函數執行 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) 2. __del__也是系統默認函數在程序結束時,對象被刪除的條件下,自動執行。 注:若是產生的對象僅僅只是python程序級別的(用戶級),那麼無需定義__del__,若是產生的 對象的同時還會向操做系統發起系統調用,即一個對象有用戶級與內核級兩種資源,好比(打開 一個文件,建立一個數據庫連接),則必須在清除對象的同時回收系統資源3,這就用到了__del__。 實際使用示例: 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() #此時在清除對象以前自動執行歸還系統資源 res=f.fobj.read() print(res) 3.__call__ :對象後面加括號,觸發執行。 構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()() class Foo: def __init__(self): pass def __str__(self): return '123123' def __del__(self): pass # 調用對象,則會自動觸發對象下的綁定方法__call__的執行, # 而後將對象自己看成第一個參數傳給self,將調用對象時括號內的值 #傳給*args與**kwargs def __call__(self, *args, **kwargs): print('__call__',args,kwargs) obj=Foo() obj(1,2,3,a=1,b=2,c=3)4、元類 1. 一切皆爲對象: 元類:類的類就是元類, 咱們用class定義的類使用來產生咱們本身的對象的 內置元類type是用來專門產生class定義的類的 二、用內置的元類type,來實例化獲得咱們的類 class_name='Chinese' class_bases=(object,) class_body=""" country="China" def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def speak(self): print('%s speak Chinese' %self.name) """ class_dic={} exec(class_body,{},class_dic) # 類的三大要素class_name,class_bases,class_dic 3 、自定義元類: 本身能夠控制類規範 class Mymeta(type): # 來控制類Foo的建立 def __init__(self,class_name,class_bases,class_dic): #self=Foo if not class_name.istitle(): raise TypeError('類名的首字母必須大寫傻叉') if not class_dic.get('__doc__'): raise TypeError('類中必須寫好文檔註釋,大傻叉') super(Mymeta,self).__init__(class_name,class_bases,class_dic) # 控制類Foo的調用過程,即控制實例化Foo的過程 def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={} #1 造一個空對象obj obj=object.__new__(self) #二、調用Foo.__init__,將obj連同調用Foo括號內的參數一同傳給__init__ self.__init__(obj,*args,**kwargs) return obj # 下一行等同於傳值 Foo=Mymeta('Foo',(object,),class_dic) class Foo(object,metaclass=Mymeta): """ 文檔註釋 """ x=1 def __init__(self,y): self.Y=y def f1(self): print('from f1') obj=Foo(1111) #Foo.__call__() 5.單例模式:適用於值重複不會改變,可節省必定資源 方式1、 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 is obj5 is obj6)