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

精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Python中元類的作用

科技綠洲 ? 來源:Python實用寶典 ? 作者:Python實用寶典 ? 2023-11-02 11:18 ? 次閱讀

1.什么是類

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

和大多數語言一樣,Python中的類知識用來描述如何“生成一個對象”:

圖片

但是,在Python中,類不僅能用來描述如何生成一個對象, 類本身也是對象

在你使用關鍵詞** class **的時候,Python就會執行它,并創建一個對象。

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

上述指令在內存中創建了一個“ObjectiveCreator”的對象。

這個對象(類)本身具有創建對象(實例)的能力,因此它也是一個類。你可以對它做以下操作:

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

例如:

圖片

2.動態創建類

由于類是對象,因此你可以像創建任何對象(數組、字典等)一樣,隨時隨地創建類。

你甚至可以在函數里創建類:

圖片

但是,這樣的類并不是很動態,因為你必須自己編寫整個類。

使用class關鍵字時,Python會幫你自動創建此對象,但是,Python同樣也提供了一種手動創建的方法,那就是type函數。

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

type函數最經典的用法是返回對象的類型。但是很少人知道,它還能接受參數并手動創建類。

type(name, bases, attrs)

其中

  • name : 類名
  • bases : 元組,父類名
  • attrs : 字典,類屬性值

因此你可以這樣手動創建類:

>> > 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})

用來繼承也是可以的:

>> > FooChild = type('FooChild', (Foo,), {})
 >> > print(FooChild)
< class '__main__.FooChild' >
 >> > print(FooChild.bar) # bar is inherited from Foo
True

可見通過 type() 函數創建的類和直接寫class是完全一樣的。

因為Python解釋器遇到class定義時,僅僅是掃描一下class定義的語法,然后調用 type() 函數創建出class。

正常情況下,我們用class來定義類,但是,type()函數也允許我們動態創建類,也就是說,動態語言本身支持運行期動態創建類,這和靜態語言有非常大的不同。

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

3.什么是元類

元類就是用于創建類的“東西”。

你定義類是為了創建對象,Python中所有的類都是對象。元類是用于創建這些對象的。可以看這個例子:

MyClass = MetaClass()
my_object = MyClass()

這有點像套娃。這段代碼轉化為type就是這樣的:

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

因此,我們可以得到一個基本事實,type 本身就是一個 元類

其實,就是 type 在幕后創建了Python中所有的類。

通過檢查__class__屬性,你會看到Python中,一切對象都是基于 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' >

那么,有個有趣的問題,__class__的__class__是什么呢?

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

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

type 是Python使用的內置元類。不過,你可以創建自己的元類。

3.1 __metaclass__屬性

在Python 2中,可以在編寫類時添加屬性__metaclass__,使用某個元類來創建該類:

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

不過要小心的是,你雖然先寫了 class Foo(object),但Foo這個對象尚未被創建,Python將先尋找__metaclass__類,找到后用它來創建Foo類。

如果沒有這個__metaclass__類,它將使用 type 來創建類。

因此,類創建的流程是這樣的:

1.創建的類中有__metaclass__元類屬性嗎?

2.如果有,那就用__metaclass__給該類在內存中創建一個類對象。

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

4.如果還是沒有,那就使用父類的元類來創建類對象。

現在的問題就是,你可以在__metaclass__中放置些什么代碼呢?

答案就是:可以創建一個類的東西。那么什么可以用來創建一個類呢?type,或者任何繼承或使用它的東西。

3.2 Python 3中的元類

設置元類的語法在Python3已改為:

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

即不再使用__metaclass__屬性,而是在基類參數列表中引入關鍵字參數。

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

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

4.為什么需要元類

元類最主要的一個應用方向是創建API,一個最著名的應用是Django ORM,比如:

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

當你這樣訪問屬性的時候:

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

它并不會返回models.IntegerField,而是返回了一個整形的數字。

這是因為models.Model引用了一個ModelBase類,該類隨后進行了魔術般地操作,使其能夠與數據庫字段進行掛鉤。

這就是元類的作用,Django通過它,完成了系列復雜的幕后工作,將原本非常復雜的事情變得非常簡單。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • python
    +關注

    關注

    56

    文章

    4782

    瀏覽量

    84453
  • 數組
    +關注

    關注

    1

    文章

    415

    瀏覽量

    25908
  • 函數參數
    +關注

    關注

    0

    文章

    6

    瀏覽量

    5982
收藏 人收藏

    評論

    相關推薦

    如何使用Python? 優勢有哪些?

      Python是一種面向對象的高級語言,因此類對于Python非常重要。是一個空間,在該空間中變量(屬性/方法)分別存儲。運算符' . '用于調用的屬性和方法。
    發表于 07-30 18:08

    Python中的方法、實例方法和靜態方法?

    Python中實例屬性和實例方法Python中類屬性和方法Python中調用方法
    發表于 11-05 06:25

    python的理解與使用

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

    python的多態和的property屬性

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

    python開發之‘’講解

    Python 在盡可能不增加新的語法和語義的情況下加入了機制。這種機制是 C++ 和 Modula-3 的混合。 Python中的沒有在用戶和定義之間建立一個絕對的屏障,而是依賴于
    發表于 03-15 14:12 ?1次下載

    揭開Python中self的神秘面紗

    許多python初學者,在接觸到python面向對象的時候,就被中包含的方法中的self打敗了,不知道self是何物?
    的頭像 發表于 01-19 17:51 ?1759次閱讀
    揭開<b class='flag-5'>Python</b><b class='flag-5'>類</b>中self的神秘面紗

    python變量的作用

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

    python的理解與使用

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

    python的繼承詳解

    python的繼承 的繼承,跟人類繁衍的關系相似。 被繼承的稱為基(也叫做父),繼承而
    的頭像 發表于 03-08 16:40 ?3077次閱讀

    10種聚介紹和Python代碼

    分享一篇關于聚的文章,10種聚介紹和Python代碼。
    的頭像 發表于 07-30 10:25 ?3024次閱讀

    簡述python和實例屬性賦值

    python主體沒有任何內容,只有pass語句,稱為空。 ## 1.2 obj.attr屬性賦值 通過obj.attr=value進行和實例屬性賦值。
    的頭像 發表于 02-21 10:30 ?1009次閱讀

    Python的屬性和方法是什么

    編程中我們用來創建對象。日常生活中的汽車設計圖就是我們Python中的。日常生活中的小汽車就是Python中的對象。
    的頭像 發表于 02-23 10:17 ?841次閱讀

    什么是python與對象

    Python中的,type函數查看數據類型
    的頭像 發表于 02-23 10:18 ?729次閱讀

    Python中的和對象詳解

    Python 是一種面向對象的編程語言,它支持和對象。是一種用戶自定義的數據類型,用于定義對象的屬性和方法。對象是的實例,它包含的屬
    的頭像 發表于 04-20 16:53 ?1059次閱讀

    Python繼承的基本規則

    繼承規則 與其他基于的語言一樣,可以通過繼承組合多個定義。 定義可以擴展(或繼承)多個其他。這些又可以擴展其他
    的頭像 發表于 09-20 14:24 ?497次閱讀