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的內建元類
- 下面開始自定義元類,並使用自定義元類創建對象
- 每個類都有一個__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將字典轉換爲列表進行遍歷