日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

深入浅出Python元编程

發布時間:2025/3/21 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入浅出Python元编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

隔壁的Java 世界為了創建一個對象搞得雞飛狗跳,這邊的Python解釋器倒是樂得清閑。?

(參見:《當創建對象時......》)

我作為他的第n任助手正式上崗。

“老大,有程序員要創建對象,怎么辦?”我向Python解釋器發出了預警,上崗后頭一次遇到這種情況,我有點緊張。

class?Person:def?sayHello(self,name):print("hello,"+name)p = Person()p.sayHello("andy")

“怕啥,我告訴你怎么做啊,首先找到Metaclass(元類),用元類來創建Class, 最后用Class對象來創建實例。” ? 老大說著還給我畫了個圖:?

?“不是吧!剛才還說人家Java雞飛狗跳,我看我們這兒也絲毫不差,一個Class(如Person)在內存中用個對象來表示我理解,畢竟在我們的世界中,一切都是對象嘛, 但是這Metaclass(元類)是什么鬼?” ?

“是啊,類是一個對象,調用這個類對象的__new__方法就可以創建出這個類的實例。那么問題來了, 類對象是怎么來的?怎么把這個類對象給new 出來?” ?老大沒有回答,只是反問。 ?

“不是程序員寫的嗎, class Person.....” ?我有點底氣不足。?

“程序員寫的只是代碼,都是文本而已,我們在執行的過程中需要用Metaclass 把這個Person類對象給創建起來的。”?

“可是我也沒有看到Person類的Metaclass啊?! 他到底在哪兒?” ?

“那是你沒有找到, Person類中沒有,就去它的父類中去找,如果也沒有,就繼續向父類的父類去找,如果在任何父類中都找不到Metaclass,就去模塊中找,如果還是找不到,就用缺省的Metaclass,即type。”?

我按照老大的要求,去找這個Metaclass,沒有找到,只好用缺省的type了。

可是我記得這個type不是個類,是個函數啊,可以用來查看一個變量的類型:

>>>?type(1) <class?'int'> >>>?type("aaa") <class?'str'> >>>

老大說:“這個type啊,還有另外一個用法,可以創建其他類對象,在創建的時候,需要三個參數:”

1. 要創建的類對象的名稱,例如"Person"?

2. 要創建的類對象的父類,例如(object)?

3. 包含屬性的字典,即類的屬性和方法。例如{"sayHello": sayHello}?

比如,下面這段代碼也創建了一個類對象Person,和程序員寫的class Person...? 效果是一樣的。

def?sayHello(self,name):print("hello,"+name)#通過type來創建一個類對象,名稱為Person,這個類對象有一個方法sayHello Person?=?type("Person",(),{"sayHello":sayHello})#通過類對象來創建實例 p?=?Person()p.sayHello("andy")??#?hello?andy?

(友情提示:可左右滑動)

嘿,這個辦法不錯啊,可以在運行時、動態地創建一個全新的類出來!隔壁的Java雖然也能做到,但是得利用ASM之類工具去直接操作字節碼,太麻煩了,我大Python直接通過普普通通、簡簡單單的Python代碼就搞定了!

這就是動態腳本語言的一個優勢吧!?

之前聽說過元編程,現在應該就是元編程了吧?但是這個Metaclass到底有什么用處呢? 程序員為什么不直接在代碼中寫class Person..... 這樣的代碼? 這樣多直觀啊。

老大說:“有些程序員會自定義Metaclass,這些自定義的Metaclass 主要做這些事情:”?

1. 攔截類的創建?

2. 讀取類的信息,可能做修改?

3. 返回新的類。?

攔截類的創建? 為什么有這樣“變態”的需求?

我真想看看一個自定義的Metaclass,看看它到底是怎么“變態”的。?

沒多久,機會來了,又要創建對象了。?

from?django.db?import?modelsclass?Employee(models.Model):name?=?models.CharField(maxlength?=?50)????age??=?models.IntegerField()#其他代碼略#

在Employee中沒有看到Metaclass, 我就去父類Model中去尋找,運氣不錯,一下子就找到了metaclass ,叫做ModelBase:

class?Model(metaclass=ModelBase):#其他代碼略

趕緊去看ModelBase的代碼,唉,實在是有點復雜了,讓我看得頭暈。?

老大說:“你不用花費時間了,你的前任的前任曾經研究過它,是為了實現ORM?!”?

“ORM?”?

“就是對象和關系數據庫的映射。你想想,程序員創建的Python對象想要保存到數據庫中,該怎么辦?“ 老大問道。

”那還不簡單,程序員可以寫SQL代碼啊,insert into employee(name,age) values(?,?),其中包含那個Employee對象的name ,age的值不就行了?“

”那樣就有點笨拙了,你再想想,能不能簡化程序員的工作,別讓他們去寫這些煩人的、容易出錯的SQL代碼?能不能讓框架來做這件事?“ 老大寫了兩行代碼。

employee?=?Employee(name="andy",age=20)?? employee.save()

“看看,程序員只要把對象創建出來,調用下save方法就行了,SQL語句就會形成,保存到數據庫中。”

(注:這里略過了數據庫連接的管理)

“難道ModelBase這個元類在后面做‘手腳'?”我似乎有點理解了。

”沒錯,你看到這些Employee類的屬性沒有? 就是程序員寫的那些name, age...... 程序員這么寫,其實就是在告訴ModelBase,尊敬的Metaclass 啊, 這些都是數據庫的列啊,列名是 name, 類型是char(50) , 還有個列名是age,是個整數。”?

?“那個MetaClass ,對,就是ModelBase會讀取這些列名、類型,并且記錄下來。 有了列名的信息,將來就可以形成insert, update,delete等SQL語句了。對不對?”

原來如此!看來ModelBase在創建Employee類對象的時候,“偷偷地”讀取了Employee類的定義信息,這樣才能在背后實現ORM!?

我按照老大的指示,調用ModelBase的__new__方法,創建了Employee類對象。?

接下來又調用Employee類對象的__new__方法,創建了Employee實例對象。 ?

employee?=?Employee(name="andy",age=20)?? employee.save()

當程序員調用employee.save()方法的時候,正如老大所說,神奇的魔法發生了,一條sql語句形成,并且發送給了數據庫去執行。

我感慨到:“這Python的元編程還是真是不錯啊,能在運行時動態地修改類,比隔壁的Java強多了!”

“Python元編程的技術不僅僅是Metaclass,還多著呢,你慢慢學吧!”

總結

以上是生活随笔為你收集整理的深入浅出Python元编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。