> > class ObjectCreator ( object ): ... pass ... 上述指令在內(nèi)存中創(chuàng)建了一個(gè)“ObjectiveCreator”的對(duì)象。 這個(gè)對(duì)象(類(lèi))本身具有創(chuàng)建對(duì)象(實(shí)例)的能力,因此它也是一個(gè)類(lèi)。你可以" />

亚洲精品久久久久久久久久久,亚洲国产精品一区二区制服,亚洲精品午夜精品,国产成人精品综合在线观看,最近2019中文字幕一页二页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python中元類(lèi)的作用

科技綠洲 ? 來(lái)源:Python實(shí)用寶典 ? 作者:Python實(shí)用寶典 ? 2023-11-02 11:18 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.什么是類(lèi)

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

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

圖片

但是,在Python中,類(lèi)不僅能用來(lái)描述如何生成一個(gè)對(duì)象, 類(lèi)本身也是對(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ì)象(類(lèi))本身具有創(chuàng)建對(duì)象(實(shí)例)的能力,因此它也是一個(gè)類(lèi)。你可以對(duì)它做以下操作:

1.將其分配給變量
2.復(fù)制它
3.為其添加屬性
4.將其作為函數(shù)參數(shù)傳遞

例如:

圖片

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

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

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

圖片

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

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

>> > print(type(1))
< type 'int' >
 >> > print(type("1"))
< type 'str' >
 >> > print(type(ObjectCreator))
< type 'type' >
 >> > print(type(ObjectCreator()))
< class '__main__.ObjectCreator' >

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

type(name, bases, attrs)

其中

  • name : 類(lèi)名
  • bases : 元組,父類(lèi)名
  • attrs : 字典,類(lèi)屬性值

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

>> > MyShinyClass = type('MyShinyClass', (), {}) # returns a class object
 >> > print(MyShinyClass)
< class '__main__.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)
< class '__main__.FooChild' >
 >> > print(FooChild.bar) # bar is inherited from Foo
True

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

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

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

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

3.什么是元類(lèi)

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

你定義類(lèi)是為了創(chuàng)建對(duì)象,Python中所有的類(lèi)都是對(duì)象。元類(lèi)是用于創(chuàng)建這些對(duì)象的??梢钥催@個(gè)例子:

MyClass = MetaClass()
my_object = MyClass()

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

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

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

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

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

>> > age = 35
 >> > age.__class__
< type 'int' >
 >> > name = 'bob'
 >> > name.__class__
< type 'str' >
 >> > def foo(): pass
 >> > foo.__class__
< type 'function' >
 >> > class Bar(object): pass
 >> > b = Bar()
 >> > b.__class__
< class '__main__.Bar' >

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

>> > age.__class__.__class__
< type 'type' >
 >> > name.__class__.__class__
< type 'type' >
 >> > foo.__class__.__class__
< type 'type' >
 >> > b.__class__.__class__
< type 'type' >

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

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

3.1 __metaclass__屬性

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

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

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

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

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

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

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

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

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

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

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

3.2 Python 3中的元類(lèi)

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

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

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

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

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

4.為什么需要元類(lèi)

元類(lèi)最主要的一個(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)你這樣訪(fǎng)問(wèn)屬性的時(shí)候:

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

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

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

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4850

    瀏覽量

    89313
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    420

    瀏覽量

    27069
  • 函數(shù)參數(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    6135
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何使用Python類(lèi)? 優(yōu)勢(shì)有哪些?

      Python是一種面向?qū)ο蟮母呒?jí)語(yǔ)言,因此類(lèi)對(duì)于Python非常重要。類(lèi)是一個(gè)空間,在該空間中變量(屬性/方法)分別存儲(chǔ)。運(yùn)算符' . '用于調(diào)用類(lèi)的屬性和方法。
    發(fā)表于 07-30 18:08

    Python中的類(lèi)方法、實(shí)例方法和靜態(tài)方法?

    Python中實(shí)例屬性和實(shí)例方法Python中類(lèi)屬性和類(lèi)方法Python中調(diào)用類(lèi)方法
    發(fā)表于 11-05 06:25

    python類(lèi)的理解與使用

    python類(lèi)的理解與使用1. 通俗理解類(lèi)類(lèi)(英文名 class),是具有相同特性(屬性)和行為(方法)的對(duì)象(實(shí)例)的抽象模板。從定義上來(lái)理解類(lèi)
    發(fā)表于 03-07 16:51

    python類(lèi)的多態(tài)和類(lèi)的property屬性

    python類(lèi)的多態(tài)多態(tài),是指在同一類(lèi)型下的不同形態(tài)。比如下面這段代碼class People: def speak(self):passclass American(People): def
    發(fā)表于 03-09 16:38

    python開(kāi)發(fā)之‘類(lèi)’講解

    Python 在盡可能不增加新的語(yǔ)法和語(yǔ)義的情況下加入了類(lèi)機(jī)制。這種機(jī)制是 C++ 和 Modula-3 的混合。 Python中的類(lèi)沒(méi)有在用戶(hù)和定義之間建立一個(gè)絕對(duì)的屏障,而是依賴(lài)于
    發(fā)表于 03-15 14:12 ?1次下載

    揭開(kāi)Python類(lèi)中self的神秘面紗

    許多python初學(xué)者,在接觸到python面向?qū)ο蟮臅r(shí)候,就被類(lèi)中包含的方法中的self打敗了,不知道self是何物?
    的頭像 發(fā)表于 01-19 17:51 ?2080次閱讀
    揭開(kāi)<b class='flag-5'>Python</b><b class='flag-5'>類(lèi)</b>中self的神秘面紗

    python變量的作用

    python變量的作用域 1. 作用Python作用域可以分為四種: L (Local) 局部作用
    的頭像 發(fā)表于 03-03 16:50 ?1983次閱讀

    python類(lèi)的理解與使用

    python類(lèi)的理解與使用 1. 通俗理解類(lèi) 類(lèi)(英文名 class),是具有相同特性(屬性)和行為(方法)的對(duì)象(實(shí)例)的抽象模板。 從定義上來(lái)理解
    的頭像 發(fā)表于 03-07 16:51 ?1991次閱讀

    python類(lèi)的繼承詳解

    python類(lèi)的繼承 類(lèi)的繼承,跟人類(lèi)繁衍的關(guān)系相似。 被繼承的類(lèi)稱(chēng)為基類(lèi)(也叫做父類(lèi)),繼承而
    的頭像 發(fā)表于 03-08 16:40 ?3556次閱讀

    10種聚類(lèi)介紹和Python代碼

    分享一篇關(guān)于聚類(lèi)的文章,10種聚類(lèi)介紹和Python代碼。
    的頭像 發(fā)表于 07-30 10:25 ?6992次閱讀

    簡(jiǎn)述python類(lèi)和實(shí)例屬性賦值

    python類(lèi)主體沒(méi)有任何內(nèi)容,只有pass語(yǔ)句,稱(chēng)為空類(lèi)。 ## 1.2 obj.attr屬性賦值 通過(guò)obj.attr=value進(jìn)行類(lèi)和實(shí)例屬性賦值。
    的頭像 發(fā)表于 02-21 10:30 ?1501次閱讀

    Python類(lèi)的屬性和方法是什么

    編程中我們用類(lèi)來(lái)創(chuàng)建對(duì)象。日常生活中的汽車(chē)設(shè)計(jì)圖就是我們Python中的類(lèi)。日常生活中的小汽車(chē)就是Python中的對(duì)象。
    的頭像 發(fā)表于 02-23 10:17 ?1360次閱讀

    什么是python類(lèi)與對(duì)象

    Python中的類(lèi),type函數(shù)查看數(shù)據(jù)類(lèi)型
    的頭像 發(fā)表于 02-23 10:18 ?1262次閱讀

    Python中的類(lèi)和對(duì)象詳解

    Python 是一種面向?qū)ο蟮木幊陶Z(yǔ)言,它支持類(lèi)和對(duì)象。類(lèi)是一種用戶(hù)自定義的數(shù)據(jù)類(lèi)型,用于定義對(duì)象的屬性和方法。對(duì)象是類(lèi)的實(shí)例,它包含類(lèi)的屬
    的頭像 發(fā)表于 04-20 16:53 ?1620次閱讀

    Python類(lèi)繼承的基本規(guī)則

    繼承規(guī)則 與其他基于類(lèi)的語(yǔ)言一樣,可以通過(guò)繼承組合多個(gè)類(lèi)定義。 類(lèi)定義可以擴(kuò)展(或繼承)多個(gè)其他類(lèi)。這些類(lèi)又可以擴(kuò)展其他
    的頭像 發(fā)表于 09-20 14:24 ?897次閱讀