Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美亚洲黄色,中文字幕精品一区二区日本大胸,日本一本高清视频

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢(xún)熱線:

          python 動(dòng)態(tài)創(chuàng)建字典_一、Python 中類(lèi)的定義、創(chuàng)建、使用

          Python 界的領(lǐng)袖 Tim Peters 說(shuō)的:

          元類(lèi)就是深度的魔法,99% 的用戶(hù)應(yīng)該根本不必為此操心。如果你想搞清楚究竟是否需要用到元類(lèi),那么你就不需要它。那些實(shí)際用到元類(lèi)的人都非常清楚地知道他們需要做什么,而且根本不需要解釋為什么要用元類(lèi)。

          所以,這篇文章,認(rèn)真閱讀一遍就好了。

          目錄

          3d80cf2207a61df9dce14481201363b3.png

          一、Python 中類(lèi)也是對(duì)象

          在了解元類(lèi)之前,我們先進(jìn)一步理解 Python 中的類(lèi),在大多數(shù)編程語(yǔ)言中,類(lèi)就是一組用來(lái)描述如何生成一個(gè)對(duì)象的代碼段。在 Python 中這一點(diǎn)也是一樣的。

          這點(diǎn)在學(xué)習(xí)類(lèi)的章節(jié)也強(qiáng)調(diào)過(guò)了,下面可以通過(guò)例子回憶一下:

          25d38469f8e7bcf784a80e0e9b81fd8a.png

          但是,Python 中的類(lèi)有一點(diǎn)跟大多數(shù)的編程語(yǔ)言不同,在 Python 中,可以把類(lèi)理解成也是一種對(duì)象。對(duì)的,這里沒(méi)有寫(xiě)錯(cuò),就是對(duì)象。

          為什么呢?

          因?yàn)橹灰褂藐P(guān)鍵字 class ,Python 解釋器在執(zhí)行的時(shí)候就會(huì)創(chuàng)建一個(gè)對(duì)象。

          如:

          class (object): pass

          當(dāng)程序運(yùn)行這段代碼的時(shí)候,就會(huì)在內(nèi)存中創(chuàng)建一個(gè)對(duì)象,名字就是。這個(gè)對(duì)象(類(lèi))自身?yè)碛袆?chuàng)建對(duì)象(類(lèi)實(shí)例)的能力,而這就是為什么它是一個(gè)類(lèi)的原因。

          但是,它的本質(zhì)仍然是一個(gè)對(duì)象,于是我們可以對(duì)它做如下的操作:

          014e7ed5961d9ae18d7b719b7c3081a7.png

          # 可以直接打印一個(gè)類(lèi),因?yàn)樗鋵?shí)也是一個(gè)對(duì)象print()# 可以直接把一個(gè)類(lèi)作為參數(shù)傳給函數(shù)(注意這里是類(lèi),是沒(méi)有實(shí)例化的)echo()# 也可以直接把類(lèi)賦值給一個(gè)變量 = ()

          輸出的結(jié)果如下:

          dcc3452d1f163d3efaf5ce6ca66366e2.png

          ?

          二、使用 type() 動(dòng)態(tài)創(chuàng)建類(lèi)

          因?yàn)轭?lèi)也是對(duì)象,所以我們可以在程序運(yùn)行的時(shí)候創(chuàng)建類(lèi)。

          Python 是動(dòng)態(tài)語(yǔ)言。

          動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言最大的不同,就是函數(shù)和類(lèi)的定義,不是編譯時(shí)定義的,而是運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的。

          在之前,我們先了了解下 type() 函數(shù)。

          首先我們新建一個(gè) hello.py 的模塊,然后定義一個(gè) Hello 的 class ,

          c99de33a6b7c7ec06ebdcf59a85d500c.png

          然后在另一個(gè)模塊中引用 hello 模塊,并輸出相應(yīng)的信息。

          其中 type() 函數(shù)的作用是可以查看一個(gè)類(lèi)型和變量的類(lèi)型。

          a93aa42e1bbe8448995cbcfe1f459d90.png

          上面也提到過(guò),type() 函數(shù)可以查看一個(gè)類(lèi)型或變量的類(lèi)型,Hello 是一個(gè) class ,它的類(lèi)型就是 type ,而 h 是一個(gè)實(shí)例,它的類(lèi)型就是 com..hello.Hello。

          前面的 com. 是我的包名,hello 模塊在該包名下。

          在這里還要細(xì)想一下,上面的例子中,我們使用 type() 函數(shù)查看一個(gè)類(lèi)型或者變量的類(lèi)型。

          其中查看了一個(gè) Hello class 的類(lèi)型,打印的結(jié)果是: 。

          其實(shí) type() 函數(shù)不僅可以返回一個(gè)對(duì)象的類(lèi)型,也可以創(chuàng)建出新的類(lèi)型。

          class 的定義是運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的,而創(chuàng)建 class 的方法就是使用 type() 函數(shù)。

          比如我們可以通過(guò) type() 函數(shù)創(chuàng)建出上面例子中的 Hello 類(lèi),具體看下面的代碼:

          e4156c0fbe83dfc03e396fda9bfdb312.png

          在這里,需先了解下通過(guò) type() 函數(shù)創(chuàng)建 class 對(duì)象的參數(shù)說(shuō)明:

          創(chuàng)建類(lèi)時(shí)首先要定義類(lèi)的_如何定義類(lèi)及創(chuàng)建對(duì)象_類(lèi)創(chuàng)建的對(duì)象稱(chēng)為什么

          1、class 的名稱(chēng),比如例子中的起名為 Hello

          2、繼承的父類(lèi)集合,注意 Python 支持多重繼承,如果只有一個(gè)父類(lèi),tuple 要使用單元素寫(xiě)法;例子中繼承 object 類(lèi),因?yàn)槭菃卧氐?tuple ,所以寫(xiě)成 (object,)

          3、class 的方法名稱(chēng)與函數(shù)綁定;例子中將函數(shù) 綁定在方法名 hello 中

          具體的模式如下:

          type(類(lèi)名, 父類(lèi)的元組(針對(duì)繼承的情況,可以為空),包含屬性的字典(名稱(chēng)和值))

          好了,了解完具體的參數(shù)使用之外,我們看看輸出的結(jié)果,可以看到,通過(guò) type() 函數(shù)創(chuàng)建的類(lèi)和直接寫(xiě) class 是完全一樣的。

          這是因?yàn)镻ython 解釋器遇到 class 定義時(shí),僅僅是掃描一下 class 定義的語(yǔ)法,然后調(diào)用 type() 函數(shù)創(chuàng)建出 class 的。

          不過(guò)一般的情況下,我們都是使用 class ***... 的方法來(lái)定義類(lèi)的,不過(guò) type() 函數(shù)也可以讓我們創(chuàng)建出類(lèi)來(lái)。

          也就是說(shuō),動(dòng)態(tài)語(yǔ)言本身支持運(yùn)行期動(dòng)態(tài)創(chuàng)建類(lèi),這和靜態(tài)語(yǔ)言有非常大的不同,要在靜態(tài)語(yǔ)言運(yùn)行期創(chuàng)建類(lèi),必須構(gòu)造源代碼字符串再調(diào)用編譯器,或者借助一些工具生成字節(jié)碼實(shí)現(xiàn),本質(zhì)上都是動(dòng)態(tài)編譯,會(huì)非常復(fù)雜。

          可以看到,在 Python 中,類(lèi)也是對(duì)象,你可以動(dòng)態(tài)的創(chuàng)建類(lèi)。

          其實(shí)這也就是當(dāng)你使用關(guān)鍵字 class 時(shí) Python 在幕后做的事情,而這就是通過(guò)元類(lèi)來(lái)實(shí)現(xiàn)的。

          三、什么是元類(lèi)

          通過(guò)上面的介紹,終于模模糊糊的帶到元類(lèi)這里來(lái)了。可是我們到現(xiàn)在還不知道元類(lèi)是什么鬼東西。

          我們創(chuàng)建類(lèi)的時(shí)候,大多數(shù)是為了創(chuàng)建類(lèi)的實(shí)例對(duì)象。

          那么元類(lèi)呢?

          元類(lèi)就是用來(lái)創(chuàng)建類(lèi)的。也可以換個(gè)理解方式就是:元類(lèi)就是類(lèi)的類(lèi)。

          通過(guò)上面 type() 函數(shù)的介紹,我們知道可以通過(guò) type() 函數(shù)創(chuàng)建類(lèi):

          MyClass = type('MyClass', (), {})

          實(shí)際上 type() 函數(shù)是一個(gè)元類(lèi)。

          type() 就是 Python 在背后用來(lái)創(chuàng)建所有類(lèi)的元類(lèi)。

          那么現(xiàn)在我們也可以猜到一下為什么 type() 函數(shù)是 type 而不是 Type呢?

          這可能是為了和 str 保持一致性,str 是用來(lái)創(chuàng)建字符串對(duì)象的類(lèi),而 int 是用來(lái)創(chuàng)建整數(shù)對(duì)象的類(lèi)。

          type 就是創(chuàng)建類(lèi)對(duì)象的類(lèi)。

          你可以通過(guò)檢查 屬性來(lái)看到這一點(diǎn)。

          Python 中所有的東西,注意喔,這里是說(shuō)所有的東西,他們都是對(duì)象。

          這包括整數(shù)、字符串、函數(shù)以及類(lèi)。它們?nèi)慷际菍?duì)象,而且它們都是從一個(gè)類(lèi)創(chuàng)建而來(lái)。

          d6762c96f05cdf735e62d6728420e496.png

          輸出的結(jié)果如下:

          可以看到,上面的所有東西,也就是所有對(duì)象都是通過(guò)類(lèi)來(lái)創(chuàng)建的,那么我們可能會(huì)好奇, 的 會(huì)是什么呢?

          換個(gè)說(shuō)法就是,創(chuàng)建這些類(lèi)的類(lèi)是什么呢?

          我們可以繼續(xù)在上面的代碼基礎(chǔ)上新增下面的代碼:

          d499165102675bea39d53442321262ac.png

          認(rèn)真觀察,再理清一下,上面輸出的結(jié)果是我們把整形 age ,字符創(chuàng) name ,函數(shù) fu 和對(duì)象實(shí)例 mEat 里 的 打印出來(lái)的結(jié)果。

          也可以說(shuō)是他們類(lèi)的類(lèi)打印結(jié)果。發(fā)現(xiàn)打印出來(lái)的 class 都是 type 。

          一開(kāi)始也提到了,元類(lèi)就是類(lèi)的類(lèi)。

          也就是元類(lèi)就是負(fù)責(zé)創(chuàng)建類(lèi)的一種東西。

          你也可以理解為,元類(lèi)就是負(fù)責(zé)生成類(lèi)的。

          而 type 就是內(nèi)建的元類(lèi)。也就是 Python 自帶的元類(lèi)。

          四、自定義元類(lèi)

          類(lèi)創(chuàng)建的對(duì)象稱(chēng)為什么_如何定義類(lèi)及創(chuàng)建對(duì)象_創(chuàng)建類(lèi)時(shí)首先要定義類(lèi)的

          到現(xiàn)在,我們已經(jīng)知道元類(lèi)是什么鬼東西了。

          那么,從始至終我們還不知道元類(lèi)到底有啥用。

          只是了解了一下元類(lèi)。

          在了解它有啥用的時(shí)候,我們先來(lái)了解下怎么自定義元類(lèi)。

          因?yàn)橹挥辛私饬嗽趺醋远x才能更好的理解它的作用。

          首先我們來(lái)了解下 屬性

          ,直譯為元類(lèi),簡(jiǎn)單的解釋就是:

          當(dāng)我們定義了類(lèi)以后,就可以根據(jù)這個(gè)類(lèi)創(chuàng)建出實(shí)例,所以:先定義類(lèi),然后創(chuàng)建實(shí)例。

          但是如果我們想創(chuàng)建出類(lèi)呢?

          那就必須根據(jù)創(chuàng)建出類(lèi),所以:先定義,然后創(chuàng)建類(lèi)。

          連接起來(lái)就是:先定義,就可以創(chuàng)建類(lèi),最后創(chuàng)建實(shí)例。

          所以, 允許你創(chuàng)建類(lèi)或者修改類(lèi)。

          換句話說(shuō),你可以把類(lèi)看成是 創(chuàng)建出來(lái)的“實(shí)例”。

          class (object): = …[…]

          如果是這樣寫(xiě)的話,Python 就會(huì)用元類(lèi)來(lái)創(chuàng)建類(lèi) 。

          當(dāng)你寫(xiě)下 class (object),但是類(lèi)對(duì)象 還沒(méi)有在內(nèi)存中創(chuàng)建。P

          ython 會(huì)在類(lèi)的定義中尋找 屬性,如果找到了,Python 就會(huì)用它來(lái)創(chuàng)建類(lèi) ,如果沒(méi)有找到,就會(huì)用內(nèi)建的 type 函數(shù)來(lái)創(chuàng)建這個(gè)類(lèi)。如果還不怎么理解,看下下面的流程圖:

          72e67a5c00c71f923d7db9cfd82c0d90.png

          再舉個(gè)實(shí)例:

          class Foo(Bar): pass

          它的判斷流程是怎樣的呢?

          首先判斷 Foo 中是否有 這個(gè)屬性?如果有,Python 會(huì)在內(nèi)存中通過(guò) 創(chuàng)建一個(gè)名字為 Foo 的類(lèi)對(duì)象(注意,這里是類(lèi)對(duì)象)。如果 Python 沒(méi)有找到 ,它會(huì)繼續(xù)在 Bar(父類(lèi))中尋找 屬性,并嘗試做和前面同樣的操作。如果 Python在任何父類(lèi)中都找不到 ,它就會(huì)在模塊層次中去尋找 ,并嘗試做同樣的操作。如果還是找不到 ,Python 就會(huì)用內(nèi)置的 type 來(lái)創(chuàng)建這個(gè)類(lèi)對(duì)象。

          其實(shí) 就是定義了 class 的行為。類(lèi)似于 class 定義了 的行為, 則定義了 class 的行為。可以說(shuō),class 是 的 。

          現(xiàn)在,我們基本了解了 屬性,但是,也沒(méi)講過(guò)如何使用這個(gè)屬性,或者說(shuō)這個(gè)屬性可以放些什么?

          答案就是:可以創(chuàng)建一個(gè)類(lèi)的東西。那么什么可以用來(lái)創(chuàng)建一個(gè)類(lèi)呢?type,或者任何使用到 type 或者子類(lèi)化 type 的東東都可以。

          元類(lèi)的主要目的就是為了當(dāng)創(chuàng)建類(lèi)時(shí)能夠自動(dòng)地改變類(lèi)。

          通常,你會(huì)為API 做這樣的事情,你希望可以創(chuàng)建符合當(dāng)前上下文的類(lèi)。假想一個(gè)很傻的例子,你決定在你的模塊里所有的類(lèi)的屬性都應(yīng)該是大寫(xiě)形式。有好幾種方法可以辦到,但其中一種就是通過(guò)在模塊級(jí)別設(shè)定 。采用這種方法,這個(gè)模塊中的所有類(lèi)都會(huì)通過(guò)這個(gè)元類(lèi)來(lái)創(chuàng)建,我們只需要告訴元類(lèi)把所有的屬性都改成大寫(xiě)形式就萬(wàn)事大吉了。

          幸運(yùn)的是, 實(shí)際上可以被任意調(diào)用,它并不需要是一個(gè)正式的類(lèi)。所以,我們這里就先以一個(gè)簡(jiǎn)單的函數(shù)作為例子開(kāi)始。

          # 元類(lèi)會(huì)自動(dòng)將你通常傳給‘type’的參數(shù)作為自己的參數(shù)傳入

          40e290f04c6b16d13ff59405ac072e35.png

          b661c379a20432770c696665c8a5c733.png

          # 請(qǐng)記住,'type'實(shí)際上是一個(gè)類(lèi),就像'str'和'int'一樣# 所以,你可以從type繼承class (type): # __new__ 是在之前被調(diào)用的特殊方法 # __new__是用來(lái)創(chuàng)建對(duì)象并返回之的方法 # 而只是用來(lái)將傳入的參數(shù)初始化給對(duì)象 # 你很少用到__new__,除非你希望能夠控制對(duì)象的創(chuàng)建 # 這里,創(chuàng)建的對(duì)象是類(lèi),我們希望能夠自定義它,所以我們這里改寫(xiě)__new__ # 如果你希望的話,你也可以在中做些事情 # 還有一些高級(jí)的用法會(huì)涉及到改寫(xiě)特殊方法,但是我們這里不用

          22e32d5dc7e19941455e56eb422e18bf.png

          # 復(fù)用type.__new__方法 # 這就是基本的OOP編程,沒(méi)什么魔法 return type.__new__(, , , )

          你可能已經(jīng)注意到了有個(gè)額外的參數(shù) ,這并沒(méi)有什么特別的。類(lèi)方法的第一個(gè)參數(shù)總是表示當(dāng)前的實(shí)例,就像在普通的類(lèi)方法中的 self 參數(shù)一樣。當(dāng)然了,為了清晰起見(jiàn),這里的名字我起的比較長(zhǎng)。但是就像 self 一樣,所有的參數(shù)都有它們的傳統(tǒng)名稱(chēng)。因此,在真實(shí)的產(chǎn)品代碼中一個(gè)元類(lèi)應(yīng)該是像這樣的:

          3e9637b65ea3be83389c6ee0e5ecda1f.png

          如果使用 super 方法的話,我們還可以使它變得更清晰一些,這會(huì)緩解繼承(是的,你可以擁有元類(lèi),從元類(lèi)繼承,從 type 繼承)

          045e40bd6e39a840e889cd8c1dbb488d.png

          通常我們都會(huì)使用元類(lèi)去做一些晦澀的事情,依賴(lài)于自省,控制繼承等等。確實(shí),用元類(lèi)來(lái)搞些“黑暗魔法”是特別有用的,因而會(huì)搞出些復(fù)雜的東西來(lái)。但就元類(lèi)本身而言,它們其實(shí)是很簡(jiǎn)單的:

          五、使用元類(lèi)


          主站蜘蛛池模板: 中文字幕一区一区三区| 武侠古典一区二区三区中文| 亚洲AV成人一区二区三区观看 | 性无码免费一区二区三区在线 | 久久免费视频一区| 中文字幕AV无码一区二区三区| 国内精品无码一区二区三区| 女同一区二区在线观看| 国产日韩一区二区三区| 少妇精品无码一区二区三区 | 国产一区二区三区乱码网站| 99精品国产高清一区二区三区| 午夜在线视频一区二区三区| 精产国品一区二区三产区| 人妻激情偷乱视频一区二区三区| 国产观看精品一区二区三区| 一区二区三区免费视频播放器| 蜜桃视频一区二区| 人妻体内射精一区二区| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲AV成人一区二区三区AV| 国产精品视频一区二区三区| 一本色道久久综合一区| 精品熟人妻一区二区三区四区不卡 | 国99精品无码一区二区三区| 无码人妻一区二区三区精品视频 | 国产一区二区电影| 午夜视频一区二区三区| 国产高清一区二区三区视频| 精品日韩一区二区| 国模极品一区二区三区| 日韩精品无码一区二区三区免费| 久久久91精品国产一区二区| 一区二区三区观看| 中文字幕一区二区三区日韩精品| 不卡一区二区在线| 国产一区二区三区乱码| 一区二区三区在线|欧| 亚洲一区二区三区精品视频| 精品视频一区二区三区四区| 无码人妻精一区二区三区 |