補充內置函數python
isinstance(obj,Foo) # 判斷obj是否是foo的實例函數
issubclass() # 判斷一個類是否是另外一個類的子類spa
反射code
什麼是反射?對象
經過字符串來操做類或者對象的屬性blog
怎麼用?繼承
hasattr(adj,’xxx’) 判斷adj有沒有’xxx’屬性ip
getattr(adj,’xxx’,None) adj有’xxx’就返回adj.xxx,沒有則返回None,若不指定第三個 參數,沒有則會報錯作用域
setattr(adj,’age’,18) adj.age = 18文檔
delattr(adj,’age’) def adj.age
內置方法
def __str__(self):在對象被打印時,自動觸發,應該在該方法內採集與對象有關的信息並return,當print(adj)是會打印__str__(self)中的return值
def __del__(self) 析構方法,對象被刪以前自動觸發
元類
什麼是元類?
python中一切皆對象,用class定義的類自己也是一個對象,負責產生該類對象的類稱爲元類
爲什麼用元類?
元類能夠負責產生類,進而控制類的產生還能夠控制對象的產生
如何用元類?
①儲備知識:
exec()
參數一:字符串形式的命令
參數二:全局做用域(字典形式),若是不指定,默認爲globals()
參數三:局部做用域(字典形式),若是不指定,默認爲locals()
能夠把exec命令的執行當成是一個函數的執行,會將執行期間產生的名字存放於局部名稱空間中
建立類的三個要素:類名,父類,類的名稱空間 #類名 class_name='Chinese' #類的父類 class_bases=(object,) #類的名稱空間 class_dic = {} #類體 class_body=""" country='China' def __init__(self,name,age): self.name=name self.age=age def talk(self): print('%s is talking' %self.name) """ exec(class_body,{},class_dic) People = type(class_name,class_bases,class_dic) # 實例化類
class運行原理:
1.拿到一個字符串形式的類名
2.拿到類的基類們
3.執行類體代碼,拿到類的名稱空間
4.調用type()再賦值給變量名
應用:自定義元類控制類的產生過程,其實就是調用元類的過程
#若是說People=type(類名,類的父類們,類的名稱空間),那麼咱們定義元類以下,來控制類的建立 class Mymeta(type): # 繼承默認元類的一堆屬性 def __init__(self, class_name, class_bases, class_dic): if '__doc__' not in class_dic or not class_dic.get('__doc__').strip(): raise TypeError('必須爲類指定文檔註釋') if not class_name.istitle(): raise TypeError('類名首字母必須大寫') super(Mymeta, self).__init__(class_name, class_bases, class_dic) class People(object, metaclass=Mymeta): country = 'China' def __init__(self, name, age): self.name = name self.age = age def talk(self): print('%s is talking' % self.name) #自定義元類,控制類的調用(即實例化)的過程 class Mymeta(type): #繼承默認元類的一堆屬性 def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('類名首字母必須大寫') super(Mymeta,self).__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs): #self=People print(self,args,kwargs) #<class '__main__.People'> ('egon', 18) {} #一、實例化People,產生空對象obj obj=object.__new__(self) #二、調用People下的函數__init__,初始化obj self.__init__(obj,*args,**kwargs) #三、返回初始化好了的obj return obj class People(object,metaclass=Mymeta): country='China' def __init__(self,name,age): self.name=name self.age=age def talk(self): print('%s is talking' %self.name) obj=People('egon',18) print(obj.__dict__) #{'name': 'egon', 'age': 18}