"""但是,python的類不止于此,類同樣也是一種對象。classObjectCreator:pass上面的代碼段將在內存中創建" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

深入了解python中元類的相關知識

系統 1772 0

類也是對象

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

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

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

            
class ObjectCreator:
  pass
          

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

  • 給它復制一個變量
  • 拷貝它
  • 給它增加屬性
  • 將它作為函數參數傳遞

示例代碼:

            
class ObjectCreator:
  pass
# 把它賦值給一個變量
a = ObjectCreator
print(a) # 
            
              
# 作為函數參數傳遞
def echo(o):
  print(o)
  
echo(ObjectCreator) # 
              
            
          

動態的創建類

因為類也是對象,所以可以在運行時動態的創建它們,使用class關鍵字即可。

            
def choose_class(name):
  if name == 'foo':
    class Foo(object):
      pass
    return Foo   # 返回的是類,不是類的實例
  else:
    class Bar(object):
      pass
    return Bar
MyClass = choose_class("foo")
print(MyClass) # 打印類對象
# 輸出結果

            
              .Foo'>
print(MyClass()) # 打印實例對象
# 輸出結果
<__main__.choose_class.
              
                .Foo object at 0x0368CFD0>
              
            
          

使用type創建類

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

語法:

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

            
MyClass = type("MyClass",(),{})
print(MyClass)
# 輸出結果:

            
          

使用type創建帶屬性的類

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

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

等價于

            
class Foo:
  bar = True
          

使用type創建繼承的子類

接著上面的代碼,我們已經創建了一個Foo類,現在來創建一個它的子類。

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

注意:

  • type的第二個參數,元組中是父類的名字,不是字符串。
  • 添加的屬性是類屬性,不是實例屬性。

使用type創建帶有方法的類

最終你會希望為你的類增加方法。只需要定義一個有著恰當簽名的函數并將其作為屬性賦值就可以了。

添加實例方法

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

添加靜態方法

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

添加類方法

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

什么是元類

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

            
MyClass =  MetaClass() # 使用元類創建類對象
MyObject = MyClass() # 使用類對象創建實例對象
          

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

            
class A:
  pass
print(A.__class__)
a = A()
print(a.__class__)
print(a.__class__.__class__)
# 輸出結果:

            
              
                
              
            
          

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

Python中所有的東西,注意,我是指所有的東西――都是對象。這包括整數、字符串、函數以及類。它們全部都是對象,而且它們都是從一個類創建而來,這個類就是type。

整數:

            
age = 18
print(age.__class__)
print(age.__class__.__class__)
# 輸出結果:

            
              
            
          

字符串:

            
name = "張三"
print(name .__class__)
print(name .__class__.__class__)
# 輸出結果:

            
              
            
          

函數:

            
def f():
  pass
print(f.__class__)
print(f.__class__.__class__)
# 輸出結果:

            
              
            
          

自定義元類

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

自定義類的主要目的:

  • 攔截類的創建
  • 修改類

使用函數實現一個自定義的元類

功能:把不是__開頭的類屬性名字變為大寫

            
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實現一個自定義元類

功能:同上

            
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'來做類對象的創建
    # return type(class_name, class_parents, newAttr)  
    # 方法2:復用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
          

效果和上面是一樣的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美成人一区二区三区不卡 | 日本精品视频一区二区三区 | 一级做人免费观看c欧美网站 | 久久久久免费精品视频 | 亚洲va欧美va人人爽夜夜嗨 | 亚洲欧美日韩一区 | 欧美另类黑人巨大videos | 朴妮唛禁福利视频在线 | 夜夜爽日日澡人人添 | 亚洲第一区在线 | 中文精品视频一区二区在线观看 | 欧美午夜艳片欧美精品 | 中文精品久久久久国产网站 | 国产免费一区二区在线看 | 九九热在线免费视频 | 奇米影视777me| 91精品视频在线播放 | 99re久久资源最新地址 | 久久国产加勒比精品无码 | 天天做夜夜做久久做狠狠 | 四虎影视在线观看2022a | 一级毛片美国一级j毛片不卡 | 欧美色视频超清在线观看 | 国产一区二区网站 | 97国产在线公开免费观看 | 四虎影院永久在线观看 | 国产尤物精品视频 | 天天拍夜夜操 | 97精品视频在线 | 免费看黄色片视频 | 手机国产日韩高清免费看片 | 精品一区二区三区在线成人 | 国产精品麻豆久久99 | 日本特级毛片 | 成人毛片在线观看 | 久久99国产精品二区不卡 | 日本不卡视频在线观看 | 美女在线视频观看影院免费天天看 | 精品一成人岛国片在线观看 | jizz成熟丰满老女人 | 91亚洲影院 |