python-元類type創建類的類、自定義元類

0x00 你創建的類真的是類嗎

class A:
    pass
print("打印類")
print(A)
print("打印類對象")
print(A())
print("類爲自己增加屬性")
A.attr1 = 10
print("類拷貝給一個變量")
B = A
print("判斷某個屬性是否爲此類的")
print(hasattr(B,"attr1"))
print("類卓偉一個參數傳入函數")
def printClass(A):
    print(A)
printClass(A)
  • 運行結果
打印類
<class '__main__.A'>
打印類對象
<__main__.A object at 0x000001EB361D0710>
類爲自己增加屬性
類拷貝給一個變量
判斷某個屬性是否爲此類的
True
類卓偉一個參數傳入函數
<class '__main__.A'>

結論 : 類同樣也是⼀種對象 。

0x01 使用內建函數type動態創建類

  • type(類名, 由⽗類名稱組成的元組(針對繼承的情況,可以爲空),包含屬 性的字典(名稱和值))
  • 使用內建函數動態創建類
# class A:
#     def __init__(self):
#         self.__age = 10
#         self.name = ""
#     def getAge(self):
#         return  self.__age
#     @staticmethod
#     def sMethod():
#         print("靜態方法")
#     @classmethod
#     def cMethod(cls):
#         print("類方法")
def getAge(self):
    return  self.__age
@staticmethod
def sMethod():
    print("靜態方法")
@classmethod
def cMethod(cls):
    print("類方法")

A = type('A',(),{"name":"","__age":10,"getAge":getAge,"sMethod":sMethod,"cMethod":cMethod})#等價於上面定義的類

a = A()
print(a.getAge())
a.sMethod()
a.cMethod()
  • 運行結果
10
靜態方法
類方法

0x02 自定義元類來創建類

a = 10
type(a )# int
a.__class__#int
a.__class__.__class__#type

type 就是 python的內建元類

  • 下面開始自定義元類,並使用自定義元類創建對象
  1. 每個類都有一個__metaclass__屬性 不定義那麼就指向type,故我們要之定義元類就必須改變其指向,指向我們定義的元類函數,可以將通過這個元類創建的類的屬性全部變爲大寫
def Mytype(cls,className, classFather, classAttrFunc):#方法一無需傳入cls
    newAttrFunc = {}
    for name, value in classAttrFunc.items():#遍歷
        if not name.startswith("__"):
            newAttrFunc[name.upper()] = value
    # 創建方法1
    return type(className, classFather, newAttrFunc)
     # 創建方法2
    return type.__new__(cls,className, classFather, newAttrFunc)
     # 創建方法3
    return super(Mytype,cls).__new__.(className, classFather, newAttrFunc)
	# super() 函數是用於調用父類(超類)的一個方法。super 是用來解決多重繼承問題的
	#  Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx

class A(object,metaclass=Mytype):#python 3寫法
    #__metaclass__ = Mytype  # 設置A類的元類爲Mytype python2寫法
    attr = "hello"


a = A()
print(hasattr(A, "attr"))
print(hasattr(A, "ATTR"))

  • for name, value in classAttrFunc.items():#for in 用於遍歷元組、列表,如需遍歷字典必須使用items將字典轉換爲列表進行遍歷
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章