python基礎之反射內置方法元類

補充內置函數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}
相關文章
相關標籤/搜索