最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python 類與元類的深度挖掘 II【經驗】

 更新時間:2016年05月06日 11:54:32   作者:rainyear  
元類在 Python 中屬于比較深層的黑魔法,在一般的日常應用中可能并不常用,但理解其背后的原理對于理解 Python 面向對象編程以及一切皆為對象的理念很有幫助;如果你需要對類進行深度改造,至少要知道從何入手。

  上一篇解決了通過調用類對象生成實例對象過程中可能遇到的命名空間相關的一些問題,這次我們向上回溯一層,看看類對象本身是如何產生的。

  我們知道 type() 方法可以查看一個對象的類型,或者說判斷這個對象是由那個類產生的:

  print(type(12))

  print(type('python'))

  class A:

  pass

  print(type(A))

  通過這段代碼可以看出,類對象 A 是由type() 產生的,也就是說 type 也可以用來產生新的對象,而且產生的是類對象,因此它是所有類對象的類:

  print(type.__doc__)

  type(object_or_name, bases, dict)

  type(object) -> the object's type

  type(name, bases, dict) -> a new type

 

  class 定義類的語法實際上轉化為 type(name, bases, dict),其中 name 參數為類的名字,bases 為繼承父類的元組,dict 為類的屬性和方法:

class A:
  pass
# 實際上等于
B = type('A', (), {})

print(A.__name__ == B.__name__)
True

  理論上說這就是元類的意義,但從實際的角度出發(fā)顯然使用 class 語法更方便、合理,而元類的實際意義則是通過繼承 type 類來構造一個新的元類,并進行特定的操作以產生具有特定行為的類對象。這樣看來它的本質與普通的類對象沒有差異,只不過繼承的是 type 類。

  在生成實例時是通過調用 __init__ 方法進行初始化的,而實際上在此之前會先調用 __new__ 方法用于創(chuàng)建實例,再通過 __init__ 初始化,就好像 __new__ 負責聲明變量,而 __init__ 負責對聲明的變量進行初始化一樣。這里有一個規(guī)則是 __new__(cls,) 的返回值必須是 cls 參數的實例,否則 __init__ 將不會觸發(fā),例如在 enum.Enum 的定義中,由于枚舉類型是單例模式,因此在定義 __new__ 的時候沒有返回其實例,也就不會進行初始化:

class Enum:

  def __new__(cls, value):

  print(cls, value)

  return value

  def __init__(self):

  print("Will not be called!")

  e = Enum(1)

   <class '__main__.Enum'> 1

  通常情況下自己定義 __new__ 需要通過調用父類的 __new__ 方法創(chuàng)建一個 cls 的實例,同樣在定義元類的時候則是調用上面提到的 type 的用法(因為元類繼承自 type):

  

class MetaEnum(type):

  def __new__(metaclass, name, base, attrs):

  print("Metaclass: {}\nName: {}\nParents: {}\nAttributes: {}".format(metaclass, name, base, attrs))

  return super().__new__(metaclass, name, base, attrs)

  class Enum(metaclass=MetaEnum):

  # Python 2.7 中定義元類的方法是使用 __metaclass__ 變量

  # [PEP 3115](https://www.python.org/dev/peps/pep-3115/)

  # 將 Python 3.0 以后語法改為 class Cls(metaclass=Meta)

  test = 0

  Metaclass: 

  Name: Enum

  Parents: ()

  Attributes: {'__qualname__': 'Enum', '__module__': '__main__', 'test': 0}

  此時我們再來看 Enum 的類,已經不再是 type 而是其元類 MetaEnum:

  type(Enum)

  __main__.MetaEnum

  除了 __new__ 方法之外,PEP 3115 還定義了 __prepare__ 屬性,用于設定初始化的命名空間(即 type 的第 3 個參數),還是以 enum.Enum 為例,我們需要限制枚舉類型中屬性名稱不得重復使用,則可以通過元類限制類的行為:

  # 定義新的字典類,在賦值新的 dict[k] = v 時

  # 檢查 k 是否重復

 class _EnumDict(dict):

  def __init__(self):

  super().__init__()

  self.members = []

  def __setitem__(self, k, v):

  if k in self.members:

  raise TypeError("Attempted to reuse key: '{}'".format(k))

  else:

  self.members.append(k)

  super().__setitem__(k, v)

  class MetaEnum(type):

  @classmethod

  def __prepare__(metaclass, cls, bases):

  return _EnumDict()

  def __new__(metaclass, name, base, attrs):

  return super().__new__(metaclass, name, base, attrs)

  class Enum(metaclass=MetaEnum):

  pass

  class Color(Enum):

  try:

  red = 1

  red = 2

  except TypeError:# 這里沒有使用 as err: 的原因是?

  print("TypeError catched")

  TypeError catched

  Python 中一切皆為對象,所有的對象都是某一類的實例,或是某一元類的實例,type 是自己的元類也是自己的實例

相關文章

  • python制作抽獎程序代碼詳解

    python制作抽獎程序代碼詳解

    在本篇內容里小編給大家整理了一篇關于python制作抽獎程序代碼詳解內容,需要的朋友們可以參考下。
    2021-01-01
  • 用python發(fā)送微信消息

    用python發(fā)送微信消息

    這篇文章主要介紹了用python發(fā)送微信消息的方法,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-12-12
  • matplotlib之pyplot模塊坐標軸范圍設置(autoscale(),xlim(),ylim())

    matplotlib之pyplot模塊坐標軸范圍設置(autoscale(),xlim(),ylim())

    這篇文章主要介紹了matplotlib之pyplot模塊坐標軸范圍設置(autoscale(),xlim(),ylim()),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Python使用missingno模塊輕松處理數據缺失

    Python使用missingno模塊輕松處理數據缺失

    missingno是一個基于Python的開源數據可視化工具,旨在幫助數據分析師和科學家更好地理解和處理數據缺失,下面我們就來看看如何使用missingno處理數據缺失吧
    2024-02-02
  • 使用python測試prometheus的實現

    使用python測試prometheus的實現

    本文主要介紹了使用python測試prometheus的實現,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • python unittest單元測試的步驟分析

    python unittest單元測試的步驟分析

    在本篇文章里小編給大家整理了一篇關于python unittest單元測試的步驟,對此有興趣的朋友們可以跟著學習下。
    2021-08-08
  • Python Collections強大的數據結構工具使用實例探索

    Python Collections強大的數據結構工具使用實例探索

    這篇文章主要介紹了Python Collections強大的數據結構工具的使用實例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • django 常用orm操作詳解

    django 常用orm操作詳解

    下面小編就為大家?guī)硪黄猟jango 常用orm操作詳解。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Python調用C語言的方法【基于ctypes模塊】

    Python調用C語言的方法【基于ctypes模塊】

    這篇文章主要介紹了Python調用C語言的方法,涉及Python基于ctypes模塊調用C語言編譯后的動態(tài)鏈接庫文件相關操作技巧,需要的朋友可以參考下
    2018-01-01
  • python獲取文件真實鏈接的方法,針對于302返回碼

    python獲取文件真實鏈接的方法,針對于302返回碼

    今天小編就為大家分享一篇python獲取文件真實鏈接的方法,針對于302返回碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05

最新評論

南康市| 安国市| 福海县| 昌邑市| 平南县| 珠海市| 都兰县| 岗巴县| 青田县| 台安县| 鹤庆县| 虹口区| 文山县| 绥阳县| 张北县| 金塔县| 蚌埠市| 赫章县| 栾城县| 增城市| 丁青县| 柘荣县| 马关县| 安宁市| 临洮县| 泸定县| 中方县| 南宫市| 扶余县| 湾仔区| 鹤壁市| 那坡县| 罗山县| 慈溪市| 温州市| 西贡区| 麟游县| 天柱县| 鱼台县| 牟定县| 界首市|