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

深入了解python中元類的相關(guān)知識(shí)

 更新時(shí)間:2019年08月29日 09:33:21   作者:三國小夢  
這篇文章主要介紹了深入了解python中的元類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

類也是對象

在大多數(shù)編程語言中,類就是一組用來描述如何生成一個(gè)對象的代碼段,在python中也是成立的。

class ObjectCreator:
  pass  
my_object = ObjectCreator()
print(my_object)
"""
輸出結(jié)果:
<__main__.ObjectCreator object at 0x037DACD0>
"""

但是,python的類不止于此,類同樣也是一種對象。

class ObjectCreator:
  pass

上面的代碼段將在內(nèi)存中創(chuàng)建一個(gè)對象,名字就叫做ObjectCreator。這個(gè)對象(類對象ObjectCreator)擁有創(chuàng)建對象(實(shí)例對象)的能力,但它本質(zhì)上仍然還是一個(gè)對象,于是你就可以對它做如下的操作:

  • 給它復(fù)制一個(gè)變量
  • 拷貝它
  • 給它增加屬性
  • 將它作為函數(shù)參數(shù)傳遞

示例代碼:

class ObjectCreator:
  pass
# 把它賦值給一個(gè)變量
a = ObjectCreator
print(a) # <class '__main__.ObjectCreator'>
# 作為函數(shù)參數(shù)傳遞
def echo(o):
  print(o)
  
echo(ObjectCreator) # <class '__main__.ObjectCreator'>

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

因?yàn)轭愐彩菍ο螅钥梢栽谶\(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建它們,使用class關(guān)鍵字即可。

def choose_class(name):
  if name == 'foo':
    class Foo(object):
      pass
    return Foo   # 返回的是類,不是類的實(shí)例
  else:
    class Bar(object):
      pass
    return Bar
MyClass = choose_class("foo")
print(MyClass) # 打印類對象
# 輸出結(jié)果
<class '__main__.choose_class.<locals>.Foo'>
print(MyClass()) # 打印實(shí)例對象
# 輸出結(jié)果
<__main__.choose_class.<locals>.Foo object at 0x0368CFD0>

使用type創(chuàng)建類

我們知道通過type()可以知道這個(gè)對象的類型是什么,他還有一個(gè)完全不同的功能,動(dòng)態(tài)的創(chuàng)建類。
type可以接受一個(gè)類的描述作為參數(shù),然后返回一個(gè)類。

語法:

type(類名,由父類名稱構(gòu)成的元組(針對繼承的情況可以為空),包含屬性的字典)

MyClass = type("MyClass",(),{})
print(MyClass)
# 輸出結(jié)果:
<class '__main__.MyClass'>

使用type創(chuàng)建帶屬性的類

type 接受一個(gè)字典來為類定義屬性,如下所示:

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

等價(jià)于

class Foo:
  bar = True

使用type創(chuàng)建繼承的子類

接著上面的代碼,我們已經(jīng)創(chuàng)建了一個(gè)Foo類,現(xiàn)在來創(chuàng)建一個(gè)它的子類。

FooChild = type("FooChild",(Foo,),{})
print(FooChild.bar) # # bar屬性是由Foo繼承而來
# 輸出結(jié)果:
True

注意:

  • type的第二個(gè)參數(shù),元組中是父類的名字,不是字符串。
  • 添加的屬性是類屬性,不是實(shí)例屬性。

使用type創(chuàng)建帶有方法的類

最終你會(huì)希望為你的類增加方法。只需要定義一個(gè)有著恰當(dāng)簽名的函數(shù)并將其作為屬性賦值就可以了。

添加實(shí)例方法

def test_f(self):
  print("添加的實(shí)例方法")
Foo = type("Foo",(),{"test_f":test_f})
f = Foo()
f.test_f()
# 輸出結(jié)果:
添加的實(shí)例方法

添加靜態(tài)方法

@staticmethod
def test_static():
  print("添加的靜態(tài)方法")
Foo = type("Foo",(),{"test_static":test_static})
Foo.test_static()
Foo.test_static()
# 輸出結(jié)果:
添加的靜態(tài)方法

添加類方法

@classmethod
def test_class(cls):
  print("添加的類方法")
Foo = type("Foo",(),{"test_class":test_class})
Foo.test_class()
# 輸出的結(jié)果:
添加的類方法

什么是元類

元類就是用來創(chuàng)建類的“東西”。元類就是就是用來創(chuàng)建類對象的,元類就是類的類。
可以這樣理解:

MyClass =  MetaClass() # 使用元類創(chuàng)建類對象
MyObject = MyClass() # 使用類對象創(chuàng)建實(shí)例對象

type函數(shù)其實(shí)就是元類。type就是在Python在背后創(chuàng)建所有類的元類,可以通過__class __屬性來查看,__class __的功能是查看對象所在的類,它可以嵌套使用。

class A:
  pass
print(A.__class__)
a = A()
print(a.__class__)
print(a.__class__.__class__)
# 輸出結(jié)果:
<class 'type'>
<class '__main__.A'>
<class 'type'>

可以看出,最后對象的類都是type元類。

Python中所有的東西,注意,我是指所有的東西——都是對象。這包括整數(shù)、字符串、函數(shù)以及類。它們?nèi)慷际菍ο?,而且它們都是從一個(gè)類創(chuàng)建而來,這個(gè)類就是type。

整數(shù):

age = 18
print(age.__class__)
print(age.__class__.__class__)
# 輸出結(jié)果:
<class 'int'>
<class 'type'>

字符串:

name = "張三"
print(name .__class__)
print(name .__class__.__class__)
# 輸出結(jié)果:
<class 'str'>
<class 'type'>

函數(shù):

def f():
  pass
print(f.__class__)
print(f.__class__.__class__)
# 輸出結(jié)果:
<class 'function'>
<class 'type'>

自定義元類

首先的了解一下metaclass屬性,用它來指定一個(gè)元類,python會(huì)在定義的類中尋找metaclass屬性,如果沒找到,就到它的父類找以此類推。如果找到了,python就會(huì)用它來創(chuàng)建類對象,如果實(shí)在沒有找到就會(huì)用內(nèi)建的type來創(chuàng)建這個(gè)類。
metaclass中可以放type或者任何使用到type或者子類化type的東東都可以。

自定義類的主要目的:

  • 攔截類的創(chuàng)建
  • 修改類

使用函數(shù)實(shí)現(xiàn)一個(gè)自定義的元類

功能:把不是__開頭的類屬性名字變?yōu)榇髮?br />

def upper_attr(future_class_name: str,future_class_parents: tuple,future_class_attr: dict):
  newAttr = {}
  for key,value in future_class_attr.items():
    if not key.startswith("__"):
      newAttr[key.upper()] = value
  return type(future_class_name,future_class_parents,newAttr)
class Foo(metaclass=upper_attr):
  name = "張三"
  age = 18

hasattr(Foo,"name") # 判斷是否有該類屬性 False
hasattr(Foo,"NAME") # True
hasattr(Foo,"age") # False
hasattr(Foo,"AGE") # True

繼承type實(shí)現(xiàn)一個(gè)自定義元類

功能:同上

class MyMetaClass(type):
  def __new__(cls, class_name: str, class_parents: tuple, class_attr: dict):
    newAttr = {}
    for key, value in class_attr.items():
      if not key.startswith("__"):
        newAttr[key.upper()] = value
    # 方法1:通過'type'來做類對象的創(chuàng)建
    # return type(class_name, class_parents, newAttr)  
    # 方法2:復(fù)用type.__new__方法
    # 這就是基本的OOP編程,沒什么魔法
    # return type.__new__(cls, class_name, class_parents, newAttr)  
    # 方法3:使用super方法
    return super(MyMetaClass, cls).__new__(cls, class_name, class_parents, newAttr)
class Foo(metaclass=MyMetaClass):
  name = "張三"
  age = 18
hasattr(Foo,"name") # 判斷是否有該類屬性 False
hasattr(Foo,"NAME") # True
hasattr(Foo,"age") # False
hasattr(Foo,"AGE") # True

效果和上面是一樣的。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • pytest進(jìn)階教程之fixture函數(shù)詳解

    pytest進(jìn)階教程之fixture函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于pytest進(jìn)階教程之fixture函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Python常用斷言函數(shù)實(shí)例匯總

    Python常用斷言函數(shù)實(shí)例匯總

    這篇文章主要介紹了Python常用斷言函數(shù)實(shí)例匯總,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 基于Python閉包及其作用域詳解

    基于Python閉包及其作用域詳解

    下面小編就為大家?guī)硪黄赑ython閉包及其作用域詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 快速進(jìn)修Python指南之自定義模塊常用模塊

    快速進(jìn)修Python指南之自定義模塊常用模塊

    這篇文章主要為大家介紹了Java開發(fā)者如何快速進(jìn)修Python指南之自定義模塊常用模塊示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • python實(shí)現(xiàn)計(jì)算資源圖標(biāo)crc值的方法

    python實(shí)現(xiàn)計(jì)算資源圖標(biāo)crc值的方法

    這篇文章主要介紹了python實(shí)現(xiàn)計(jì)算資源圖標(biāo)crc值的方法,通過解析資源文件找到icon的數(shù)據(jù),從而實(shí)現(xiàn)該功能,需要的朋友可以參考下
    2014-10-10
  • Python實(shí)現(xiàn)3行代碼解簡單的一元一次方程

    Python實(shí)現(xiàn)3行代碼解簡單的一元一次方程

    這篇文章主要介紹了Python實(shí)現(xiàn)3行代碼解簡單的一元一次方程,很適合Python初學(xué)者學(xué)習(xí)借鑒,需要的朋友可以參考下
    2014-08-08
  • 初探利用Python進(jìn)行圖文識(shí)別(OCR)

    初探利用Python進(jìn)行圖文識(shí)別(OCR)

    這篇文章主要介紹了初探利用Python進(jìn)行圖文識(shí)別(OCR),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • 關(guān)于Pycharm無法debug問題的總結(jié)

    關(guān)于Pycharm無法debug問題的總結(jié)

    今天小編就為大家分享一篇關(guān)于Pycharm無法debug問題的總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 如何使用五行Python代碼輕松實(shí)現(xiàn)批量摳圖

    如何使用五行Python代碼輕松實(shí)現(xiàn)批量摳圖

    簡單來說,摳圖就是將照片的主體人或物品從圖片中摳出來,以便貼到別處使用,下面這篇文章主要給大家介紹了關(guān)于如何使用五行Python代碼輕松實(shí)現(xiàn)批量摳圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • 解決Pycharm界面的子窗口不見了的問題

    解決Pycharm界面的子窗口不見了的問題

    今天小編就為大家分享一篇解決Pycharm界面的子窗口不見了的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01

最新評論

枣阳市| 乡宁县| 那坡县| 启东市| 高青县| 太康县| 任丘市| 灵丘县| 定襄县| 新郑市| 德钦县| 鞍山市| 鹤庆县| 通州市| 康定县| 靖远县| 扶沟县| 桑日县| 通渭县| 子长县| 鄂尔多斯市| 和龙市| 普陀区| 通州区| 兖州市| 汤原县| 泰和县| 湖南省| 齐齐哈尔市| 九龙坡区| 巧家县| 赞皇县| 芒康县| 青龙| 清原| 织金县| 交城县| 天门市| 藁城市| 卢湾区| 富顺县|