成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

再有人問什么是元類,就把這篇文章扔給他!

王巖威 / 2583人閱讀

摘要:同時(shí),在元類中,我們還需要加上一個判斷,只有在這個類創(chuàng)建時(shí)才需要控制其類的生成,其他的就不需要了。完整代碼后臺回復(fù)元類獲取原創(chuàng)不易,如果文章對你有用的話,點(diǎn)贊留言轉(zhuǎn)發(fā)是對我的最大支持日常學(xué)代碼不止,還有美和樂趣

我之前在深入理解python中的類和對象中說過,python中的類也是一個對象,可以說是類對象,可以由type來創(chuàng)建類對象的。有了這個知識我們先看看下面這個函數(shù):

這個可以根據(jù)我們傳遞的參數(shù)來指定生成相關(guān)的對象,可以說是很簡單地動態(tài)創(chuàng)建類,我們再看看結(jié)果:

這里輸入的參數(shù)為 user,所以最好的結(jié)果就是生成了?User?這個類,這個方法雖然是簡單,但是當(dāng)里面類的邏輯越來越多的時(shí)候這個類里寫的代碼就會非常地多,就會變得很臃腫了,不好看,所以這種方法不合適。

我們再看看 type() 這個方法,之前說它可以動態(tài)創(chuàng)建一個類,那我們現(xiàn)在看看到底怎樣創(chuàng)建?

在pycharm編輯器上,進(jìn)入 type() 的內(nèi)部源碼查看,可以看到:

第三行說的就是創(chuàng)建一個新類,接收的是三個參數(shù),通過名字很容易就知道這三個參數(shù)的意義:

name:類的名稱

bases:基類,就是所需要繼承的類

dict:類的屬性,包括方法

那既然知道了就創(chuàng)建一個來看看。

這個可以看到我創(chuàng)建了一個 person 的類,沒有基類,注意基類這個接收的是一個元組,屬性只有一個 name 屬性。這個是不是很簡單很直接,如果需要增加方法,也只是在 dict 參數(shù)加上對應(yīng)的方法名即可,如下:

我們知道能創(chuàng)建類的類就是元類,所以說type也是一個元類。這個還比較簡單,因?yàn)榫腿齻€參數(shù),按照規(guī)則來就可以了,但是這個只能是動態(tài)生成類,不能對類的生成過程做操作,也就是說不能控制類是如何生成的,所以在 python3 中還有個元類:metaclass,這個也是可以動態(tài)創(chuàng)建類的,比?type這個方法能操作的東西多了,但同時(shí)也有點(diǎn)難。

在說metaclass之前,先說下類是如何生成的,類分兩種。

普通的類,不通過 metaclass 來創(chuàng)建的,這個就簡單,就是通過type來創(chuàng)建類對象。

第二種,就是使用 metaclass 的,這時(shí)就通過 metaclass 來創(chuàng)建類,如果此類沒有,就會去尋找父類的 metaclass ,再沒有,還是會繼續(xù)往上找,直至找到。

再說下為什么要使用 metaclass 來創(chuàng)建類呢?

將創(chuàng)建類對象的過程委托給元類來做,不需要再在類內(nèi)部來操作,這樣代碼的分離性比較強(qiáng)

可以檢查該類有沒有實(shí)現(xiàn)父類的那些抽象方法,沒有重載的話就可以直接拋異常,不讓創(chuàng)建成功

還有很多,以后見到再補(bǔ)充說明,還有就是你會見到很多框架都會使用metaclass?來創(chuàng)建類的,要想成為一名好的 python 工程師,元類這一關(guān)必須過的。

說了,那么多,舉個小栗子來說明怎么使用 metaclass 來創(chuàng)建類吧!

可以看到,在類中指明 metaclass 來控制類的生成,這時(shí)所指向 metaclass 必須繼承t ype 這個類才可以。我們還在 metaclass 這個類中通過修改__new__這個方法來控制類的實(shí)現(xiàn),這時(shí)就可以將__init__和__new__這兩個方法分離出來了。

下面再來通過實(shí)現(xiàn)一個 orm 框架類體現(xiàn)通過元類創(chuàng)建類的好處。因?yàn)榇蠹叶贾涝趐ython中使用 pymysql 這個庫來操作 mysql 是很煩,所以才會有了這個 orm 框架,這里引用下廖雪峰的官網(wǎng)的一段話:

ORM全稱“Object Relational Mapping”,即對象-關(guān)系映射,就是把關(guān)系數(shù)據(jù)庫的一行映射為一個對象,也就是一個類對應(yīng)一個表,這樣,寫代碼更簡單,不用直接操作SQL語句。

要編寫一個ORM框架,所有的類都只能動態(tài)定義,因?yàn)橹挥惺褂谜卟拍芨鶕?jù)表的結(jié)構(gòu)定義出對應(yīng)的類來。

talk is cheap show you the code.

這個是我們在使用 orm 框架時(shí)希望是上面這樣調(diào)用的,這里就簡單定義兩個字段 name 和 age,User 類中還有個內(nèi)部類是 Meta ,這里面用了定義數(shù)據(jù)表的其他屬性,與字段定義分開,所以里面定義了一個數(shù)據(jù)表名稱。在使用 save() 方法保存的時(shí)候就是內(nèi)部拼接 mysql 語句,等下實(shí)現(xiàn)。

接下來先對兩個字段類實(shí)現(xiàn)。

這個是對 IntField 類的實(shí)現(xiàn),可以看到里面很多邏輯,同時(shí) CharField 這個類也是這樣實(shí)現(xiàn)的。

接下來是對 metaclass 的實(shí)現(xiàn)

這個__new__的方法就是對類的生成的控制,我們可以斷點(diǎn)看看,里面的參數(shù)是什么

可以看到,經(jīng)過拆包,args可以分為三個參數(shù),一個類名稱,另一個為元組,就是基類,還有一個就是類的屬性,所以可以把上面的參數(shù)改為下面的更好操作。

下面我們需要對attrs的參數(shù)里的字段進(jìn)行抽取出來,但是在判斷的時(shí)候需要判斷的東西很多,比如需要判斷是 CharField 或者 IntField 才進(jìn)行抽取,這樣如果字段多了的話寫的代碼就會很多,有一個技巧就是讓所有的字段都共同繼承一個基類 Field,然后判斷是不是這個基類即可。

這個元類基本上是完成了,最后記得調(diào)用父類的__new__進(jìn)行返回,要不然會創(chuàng)建類對象失敗,從而調(diào)用不了__init__方法來實(shí)例對象。

這里還有一個問題,就是用戶在創(chuàng)建 User 時(shí)候可能會直接存入字段信息,就比如下面這個:

user?= User("張三",?23)  


所以我們還需要在 User 類中實(shí)現(xiàn) __init__ 方法,但是如果直接在 User 類中添加這個方法的話就不太好看了,我們可以再實(shí)現(xiàn)一個基類 BaseModel ,在這個類中添加 __init__ 方法,這樣就比較好,而且還可以實(shí)現(xiàn) save() 這個方法。

在使用了另一個基類 BaseModel 之后,將這個基類來用 metaclass 來實(shí)現(xiàn),同時(shí) User 就不需要實(shí)現(xiàn) metaclass 了,只需要繼承此基類就好,因?yàn)?meta class 會向上查找,只需要父類實(shí)現(xiàn)就可以了。同時(shí),在元類 Model中,我們還需要加上一個判斷,只有在 User 這個類創(chuàng)建時(shí)才需要控制其類的生成,其他的就不需要了。

這時(shí)再看看基類 BaseModel 的 __init__ 方法如何實(shí)現(xiàn)的。

通過 setattr() 方法來進(jìn)行賦值就簡單多了,不需要一個一個判斷完再取出來。

剩下的就只有 save 方法沒有實(shí)現(xiàn)了,這個方法就簡單多了,只需要實(shí)現(xiàn)拼接 mysql 語句就可以了,這里需要拼接的語句是

sql = "insert?user(name, age)?values?("",?23)"  


再看看代碼實(shí)現(xiàn)

以上就是整個 orm框架的實(shí)現(xiàn)了,是不是看起來很簡單?卻解決了 繁雜的 mysql 操作語句。

最后運(yùn)行下就會看到一個完整的 mysql 語句出現(xiàn)。

如果我們在需要添加別的類型字段的話就只需要實(shí)現(xiàn)下這個類就好,其他的都不需要管了,是不是超級方便的?

寫在最后

如果看不不懂得話建議多敲代碼幾篇,然后打上斷點(diǎn)跟著代碼一段一段思考,這樣子就會好理解多了,還有就是看了很多遍還是不懂的話可以先放下,畢竟有 99% 的時(shí)候都不需要用這個元類,因?yàn)閷?shí)在是太麻煩了,等以后回來再看也不遲。

完整代碼后臺回復(fù)「元類」獲取

ps:原創(chuàng)不易,如果文章對你有用的話,點(diǎn)贊留言轉(zhuǎn)發(fā)是對我的最大支持!

日常學(xué)python

代碼不止bug,還有美和樂趣

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42244.html

相關(guān)文章

  • 以后有面試官你跳躍表,你把這文章給他

    摘要:跳躍表的空間復(fù)雜度為。不過,二叉查找樹是有可能出現(xiàn)一種極端的情況的,就是如果插入的數(shù)據(jù)剛好一直有序,那么所有節(jié)點(diǎn)會偏向某一邊。例如這種接結(jié)構(gòu)會導(dǎo)致二叉查找樹的查找效率變?yōu)檫@會使二叉查找樹大打折扣。假如我們要用某種數(shù)據(jù)結(jié)構(gòu)來維護(hù)一組有序的int型數(shù)據(jù)的集合,并且希望這個數(shù)據(jù)結(jié)構(gòu)在插入、刪除、查找等操作上能夠盡可能著快速,那么,你會用什么樣的數(shù)據(jù)結(jié)構(gòu)呢? 數(shù)組 一種很簡單的方法應(yīng)該就是采用數(shù)組了...

    nidaye 評論0 收藏0
  • 如果有人你ZooKeeper是什么,把這文章發(fā)給他。

    摘要:所以,雅虎的開發(fā)人員就試圖開發(fā)一個通用的無單點(diǎn)問題的分布式協(xié)調(diào)框架,以便讓開發(fā)人員將精力集中在處理業(yè)務(wù)邏輯上。在立項(xiàng)初期,考慮到之前內(nèi)部很多項(xiàng)目都是使用動物的名字來命名的例如著名的項(xiàng)目雅虎的工程師希望給這個項(xiàng)目也取一個動物的名字。 前言 提到ZooKeeper,相信大家都不會陌生。Dubbo,Kafka,Hadoop等等項(xiàng)目里都能看到它的影子。但是你真的了解 ZooKeeper 嗎?如...

    suosuopuo 評論0 收藏0
  • [譯]什么元類metaclass?

    摘要:如果還是沒有找到,就會使用父類中的元類來創(chuàng)建類。元類通常用于處理比較復(fù)雜的情況。這是因?yàn)槭褂昧嗽悾鼤⒅卸x的字段轉(zhuǎn)換成數(shù)據(jù)庫中的字段。中所有數(shù)據(jù)類型都是對象,它們要么是類的實(shí)例要么是元類的實(shí)例。 原文地址:what is metaclass in Python?我的簡書地址::nummy 類即對象 在理解元類之前,需要先掌握Python中的類,Python中類的概念與SmallT...

    zsirfs 評論0 收藏0
  • python 類和元類(metaclass)的理解和簡單運(yùn)用

    摘要:什么是元類剛才說了,元類就是創(chuàng)建類的類。類上面的屬性,相信愿意了解元類細(xì)節(jié)的盆友,都肯定見過這個東西,而且為之好奇。使用了這個魔法方法就意味著就會用指定的元類來創(chuàng)建類了。深刻理解中的元類 (一) python中的類 今天看到一篇好文,然后結(jié)合自己的情況總結(jié)一波。這里討論的python類,都基于python2.7x以及繼承于object的新式類進(jìn)行討論。 首先在python中,所有東西都...

    zhangqh 評論0 收藏0
  • 以后有人你selenium是什么,你把這文章給他

    摘要:不同目標(biāo)的自動化測試有不同的測試工具,但是任何工具都無不例外的需要編程的過程,實(shí)現(xiàn)源代碼,也可以稱之為測試腳本。 寫在最前面:目前自動化測試并不屬于新鮮的事物,或者說自動化測試的各種方法論已經(jīng)層出不窮,但是,能夠在項(xiàng)目中持之以恒的實(shí)踐自動化測試的團(tuán)隊(duì),卻依舊不是非常多。有的團(tuán)隊(duì)知道怎么做,做的還不夠好;有的團(tuán)隊(duì)還正在探索和摸索怎么做,甚至還有一些多方面的技術(shù)上和非技術(shù)上的舊系統(tǒng)需要重構(gòu)……...

    Keven 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<