<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## 知識儲備 ### 1.exec函數 * exec:三個參數 參數一:字符串形式的命令 參數二:全局作用域(字典形式),如果不指定,默認為globals() 參數三:局部作用域(字典形式),如果不指定,默認為locals() * **exec的使用** 可以把exec命令的執行當成是一個函數的執行,會將執行期間產生的名字存放于局部名稱空間中 ~~~ g={'x':1,'y':2} l={} exec(''' global x,z x=100 z=200 m=300''',g,l) print(g) #輸出:{'x': 100, 'y': 2,......,'z':200} print(l) #輸出:{'m': 300} ~~~ ### 2.一切皆對象 python中一切皆是對象,具體來說對象都有這四個特征,也可以說有這四個特征的都是對象 1. 都可以被引用,x=obj 2. 都可以當作函數的參數傳入 3. 都可以當作函數的返回值 4. 都可以當作容器類的元素,如`l=[func,time,obj,1]` 既然一切皆是對象,那類本身也是一個對象,那類又是由哪個類產生的呢? ~~~ class Foo: pass obj=Foo() #type函數可以查看類型,也可以用來查看對象的類,二者是一樣的 print(type(obj)) # 輸出:<class '__main__.Foo'> 表示,obj 對象由Foo類創建 print(type(Foo)) # 輸出:<type 'type'> 表示Foo對象有tupe類創建 ~~~ ### 3.type的語法 語法:`type(name, bases, dict)`,如:`type('Foo',(object,),{})` type 接收三個參數: * 第 1 個參數Foo是字符串,表示類名 * 第 2 個參數是元組 (object, ),表示所有的父類 * 第 3 個參數是字典,這里是一個空字典,表示沒有定義屬性和方法 ## 元類的知識 ### 什么是元類? 產生類的類稱之為元類,默認所有用class定義的類,他們的元類是type 元類是用來控制如何創建類的,正如類是創建對象的模板一樣,而元類的主要目的是為了控制類的創建行為 type是python的一個內建元類,用來直接控制生成類,python中任何class定義的類其實都是type類實例化的對象 ### 創建類方式1:使用class ~~~ class Chinese(object): country='China' def __init__(self,name,age): self.name=name self.age=age def talk(self): print('%s is talking' %self.name) ~~~ ### 創建類方式2:使用type 使用type模擬class創建類的過程,需要就是把class建類的步驟拆分開,手動去創建 * 準備工作: 定義類的三要素:類名,類的基類,類的名稱空間(類體-->exec) 類的名稱空間需要通過exec執行類體方法獲取 * 定義類名,基類,類體 ~~~ class_name='Chinese' #類名 class_bases=(object,) #類的基類 #類體 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_dic={} exec(class_body,globals(),class_dic) print(class_dic) #輸出: {'country': 'China',......} ~~~ * 調用元類type來產生類Chinense ~~~ Chinese1=type(class_name,class_bases,class_dic) obj1=Chinese1('noah',18) print(obj1,obj1.name,obj1.age) ~~~ ## 自定義元類控制類的行為 通過自定義的元類,可以做到控制類的創建,控制類的實例化,基于元類實現單例模式等,下面分別演示這三個功能 ### 1.控制類的創建行為 我們對類的創建做兩個行為控制,第一個是類名首字母必須大寫,第二個是必須寫注釋 >關于注釋的說明:我們創建類的時候,如果有寫備注的話,類的名稱空間中就會有`__dic__`熟悉,可以通過判斷這一熟悉是否存在并是否為空來判斷是否有些注釋 ~~~ #1.基于type自定義一個元類Mymeta 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) #通過super直接繼承type父類的初始化方法 #2. 基于Mymeta創建一個類people 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) ~~~ ### 2.控制類的實例化行為 1. 儲備知識:`__call__`方法 在類的內置方法那里學過call方法,用途是將讓對象可以再次被調用,而類之所以能被調用,就說明: 元類內部也應有有一個`__call__`方法,會在調用類的時觸被執行 * 元類中的call方法需要完成三件事: 1:先造一個空對象obj 2:初始化對象obj 3:返回對象obj 2. 創建一個可控制實例化的元類 ``` # A.創建包含call方法的元類Mymeta class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): super(Mymeta,self).__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18) #1:先造一個空對象obj obj=object.__new__(self) #2:初始化obj self.__init__(obj,*args,**kwargs) #3:返回obj return obj #B. 基于Mymeta創建一個類Chinese class Chinese(object,metaclass=Mymeta): country='China' def __init__(self,namem,age): self.name=namem self.age=age def talk(self): print('%s is talking' %self.name) #C.實例化對象obj obj=Chinese('noah',age=18) #等于:Chinese.__call__(Chinese,'egon',18) print(obj.__dict__) #輸出:{'name': 'noah', 'age': 18} ``` ## 元類實現單例模式 ### 單例模式是什么 單例模式就是指,如果實例化的對象數據是一樣的,就沒有必要分配兩個內存地址去存儲它,以便節約內存,例如: ``` >>> a,b=1,1 >>> id(a),id(b) (1490068576, 1490068576) ``` 那如果是自定義的類,類中的數據不變化(如mqsql端口信息),實例化的對象ID一樣嗎? ~~~ class mysql: def __init__(self): self.host='127.0.0.1' self.port=3306 obj1=mysql() obj2=mysql() print(obj1) print(obj2) #輸出: <__main__.mysql object at 0x000002519D69A240> <__main__.mysql object at 0x000002519D69A6D8> ~~~ ### 通過綁定類方法實現[常規] ``` class MySQL: __instance=None def __init__(self): self.host='127.0.0.1' self.port=3306 @classmethod def singleton(cls): if not cls.__instance: obj=cls() cls.__instance=obj return cls.__instance def conn(self): pass obj1=MySQL.singleton() obj2=MySQL.singleton() print(obj1) print(obj2) #輸出: <__main__.Mysql object at 0x0000019F876AA710> <__main__.Mysql object at 0x0000019F876AA710> ``` ### 通過自定義元類的方法實現 ``` class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): super(Mymeta,self).__init__(class_name,class_bases,class_dic) self.__instance=None def __call__(self, *args, **kwargs): if not self.__instance: obj=object.__new__(self) self.__init__(obj) self.__instance=obj return self.__instance class Mysql(object,metaclass=Mymeta): def __init__(self): self.host='127.0.0.1' self.port=3306 def conn(self): pass obj1=Mysql() obj2=Mysql() print(obj1 is obj2) 輸出: <__main__.Mysql object at 0x0000019220B4A908> <__main__.Mysql object at 0x0000019220B4A908> ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看