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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python 什么是原类_Python 什么是元类(metaclasses)?

發(fā)布時(shí)間:2023/12/4 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 什么是原类_Python 什么是元类(metaclasses)? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.什么是類

在理解元類之前,我們必須先掌握Python中的類(class)。

和大多數(shù)語(yǔ)言一樣,Python中的類知識(shí)用來(lái)描述如何“生成一個(gè)對(duì)象”:

但是,在Python中,類不僅能用來(lái)描述如何生成一個(gè)對(duì)象,類本身也是對(duì)象。

在你使用關(guān)鍵詞 class 的時(shí)候,Python就會(huì)執(zhí)行它,并創(chuàng)建一個(gè)對(duì)象。

>>> class ObjectCreator(object):... pass...

上述指令在內(nèi)存中創(chuàng)建了一個(gè)“ObjectiveCreator”的對(duì)象。

這個(gè)對(duì)象(類)本身具有創(chuàng)建對(duì)象(實(shí)例)的能力,因此它也是一個(gè)類。你可以對(duì)它做以下操作:

1.將其分配給變量

2.復(fù)制它

3.為其添加屬性

4.將其作為函數(shù)參數(shù)傳遞

例如:

2.動(dòng)態(tài)創(chuàng)建類

由于類是對(duì)象,因此你可以像創(chuàng)建任何對(duì)象(數(shù)組、字典等)一樣,隨時(shí)隨地創(chuàng)建類。

你甚至可以在函數(shù)里創(chuàng)建類:

鄭州哪里的婦科醫(yī)院好http://www.zztjfk.com/

鄭州婦科醫(yī)院哪里好http://www.zzyytj.com/

但是,這樣的類并不是很動(dòng)態(tài),因?yàn)槟惚仨氉约壕帉懻麄€(gè)類。

使用class關(guān)鍵字時(shí),Python會(huì)幫你自動(dòng)創(chuàng)建此對(duì)象,但是,Python同樣也提供了一種手動(dòng)創(chuàng)建的方法,那就是type函數(shù)。

>>> print(type(1))>>> print(type("1"))>>> print(type(ObjectCreator))>>> print(type(ObjectCreator()))

type函數(shù)最經(jīng)典的用法是返回對(duì)象的類型。但是很少人知道,它還能接受參數(shù)并手動(dòng)創(chuàng)建類。

type(name, bases, attrs)

其中

name: 類名

bases: 元組,父類名

attrs: 字典,類屬性值

因此你可以這樣手動(dòng)創(chuàng)建類:

>>> MyShinyClass = type('MyShinyClass', (), {}) # returns a class object>>> print(MyShinyClass)>>> print(MyShinyClass()) # create an instance with the class<__main__.MyShinyClass object at 0x8997cec>

如果你想給它賦予屬性,可以這樣玩:

>>> class Foo(object):... bar = True

等同于

>>> Foo = type('Foo', (), {'bar':True})

用來(lái)繼承也是可以的:

>>> FooChild = type('FooChild', (Foo,), {})>>> print(FooChild)>>> print(FooChild.bar) # bar is inherited from FooTrue

可見通過(guò) type() 函數(shù)創(chuàng)建的類和直接寫class是完全一樣的。

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

正常情況下,我們用class來(lái)定義類,但是,type()函數(shù)也允許我們動(dòng)態(tài)創(chuàng)建類,也就是說(shuō),動(dòng)態(tài)語(yǔ)言本身支持運(yùn)行期動(dòng)態(tài)創(chuàng)建類,這和靜態(tài)語(yǔ)言有非常大的不同。

Python是通過(guò)什么做到這一切的?那就是元類。

3.什么是元類

元類就是用于創(chuàng)建類的“東西”。

你定義類是為了創(chuàng)建對(duì)象,Python中所有的類都是對(duì)象。元類是用于創(chuàng)建這些對(duì)象的。可以看這個(gè)例子:

MyClass = MetaClass()my_object = MyClass()

這有點(diǎn)像套娃。這段代碼轉(zhuǎn)化為type就是這樣的:

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

因此,我們可以得到一個(gè)基本事實(shí),type 本身就是一個(gè)元類。

其實(shí),就是 type 在幕后創(chuàng)建了Python中所有的類。

通過(guò)檢查__class__屬性,你會(huì)看到Python中,一切對(duì)象都是基于 type 的:

>>> age = 35>>> age.__class__>>> name = 'bob'>>> name.__class__>>> def foo(): pass>>> foo.__class__>>> class Bar(object): pass>>> b = Bar()>>> b.__class__

那么,有個(gè)有趣的問(wèn)題,__class__的__class__是什么呢?

>>> age.__class__.__class__>>> name.__class__.__class__>>> foo.__class__.__class__>>> b.__class__.__class__

因此,元類只是創(chuàng)建類對(duì)象的東西,如果愿意,可以將其稱為“類的工廠”。

type 是Python使用的內(nèi)置元類。不過(guò),你可以創(chuàng)建自己的元類。

3.1 __metaclass__屬性

在Python 2中,可以在編寫類時(shí)添加屬性__metaclass__,使用某個(gè)元類來(lái)創(chuàng)建該類:

class Foo(object): __metaclass__ = something... [...]

不過(guò)要小心的是,你雖然先寫了 class Foo(object),但Foo這個(gè)對(duì)象尚未被創(chuàng)建,Python將先尋找__metaclass__類,找到后用它來(lái)創(chuàng)建Foo類。

如果沒有這個(gè)__metaclass__類,它將使用 type 來(lái)創(chuàng)建類。

因此,類創(chuàng)建的流程是這樣的:

1.創(chuàng)建的類中有__metaclass__元類屬性嗎?

2.如果有,那就用__metaclass__給該類在內(nèi)存中創(chuàng)建一個(gè)類對(duì)象。

3.如果Python找不到__metaclass__,它將在MODULE級(jí)別查找__metaclass__屬性 。

4.如果還是沒有,那就使用父類的元類來(lái)創(chuàng)建類對(duì)象。

現(xiàn)在的問(wèn)題就是,你可以在__metaclass__中放置些什么代碼呢?

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

3.2 Python 3中的元類

設(shè)置元類的語(yǔ)法在Python3已改為:

class Foo(object, metaclass=something): ...

即不再使用__metaclass__屬性,而是在基類參數(shù)列表中引入關(guān)鍵字參數(shù)。

不過(guò)元類的基本工作方式不變。在Python3中,你可以將屬性作為關(guān)鍵字參數(shù)傳遞給元類:

class Foo(object, metaclass=something, kwarg1=value1, kwarg2=value2): ...

4.為什么需要元類

元類最主要的一個(gè)應(yīng)用方向是創(chuàng)建API,一個(gè)最著名的應(yīng)用是Django ORM,比如:

class Person(models.Model): name = models.CharField(max_length=30) age = models.IntegerField()

當(dāng)你這樣訪問(wèn)屬性的時(shí)候:

person = Person(name='bob', age='35')print(person.age)

它并不會(huì)返回models.IntegerField,而是返回了一個(gè)整形的數(shù)字。

這是因?yàn)閙odels.Model引用了一個(gè)ModelBase類,該類隨后進(jìn)行了魔術(shù)般地操作,使其能夠與數(shù)據(jù)庫(kù)字段進(jìn)行掛鉤。

這就是元類的作用,Django通過(guò)它,完成了系列復(fù)雜的幕后工作,將原本非常復(fù)雜的事情變得非常簡(jiǎn)單。

總結(jié)

以上是生活随笔為你收集整理的python 什么是原类_Python 什么是元类(metaclasses)?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。