__class__屬性
__class__屬性可以查看對象的類型.
class Person(object):
pass
person = Person()
print(person.__class__)
# 運(yùn)行結(jié)果
# <class '__main__.Person'>
Person 類的實(shí)例對象person 的類型時Person 類類型, Python 是面向?qū)ο蟮恼Z言, 那么Person 的類對象的類型又是什么?
class Person(object):
pass
person = Person()
print(person.__class__)
print(Person.__class__)
# int 的類型
print(int.__class__)
# str 的類型
print(str.__class__)
# 運(yùn)行結(jié)果
# <class '__main__.Person'>
# <class 'type'>
# <class 'type'>
# <class 'type'>
Person / int / str 的類對象的類型都是type 類類型.
那么type類對象 的類型又是什么類型?
class Person(object):
pass
print(Person.__class__.__class__)
# int 的類型
print(int.__class__.__class__)
# str 的類型
print(str.__class__.__class__)
print(type.__class__)
# 運(yùn)行結(jié)果
# <class 'type'>
# <class 'type'>
# <class 'type'>
# <class 'type'>
type 類對象的類型還是type 類類型, 那么type 類是干嘛的?
元類
type 類是元類, Python中所有的類默認(rèn)都是使用type 類創(chuàng)建的, type 類屬于Python中的高深魔法, 一般很少用到.
"""
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
"""
type類有兩個功能,
- type(object) : 一個參數(shù),返回object 的類型
- type(name, bases, dict) : 三個參數(shù),返回一個新的類型
type(object)
class Person(object):
pass
person = Person()
print(type(person)) # 查看person 實(shí)例對象的類型
print(type(Person)) # 查看Person 類對象的類型
# 運(yùn)行結(jié)果
# <class '__main__.Person'>
# <class 'type'>
type(name, bases, dict)
使用type 創(chuàng)建一個類
正常創(chuàng)建Person 類的子類Teacher
class Person(object):
pass
class Teacher(Person):
def __init__(self):
self.name = "Teacher"
# help() 函數(shù)用于查看函數(shù)或模塊用途的詳細(xì)說明。
print(help(Teacher))
元類創(chuàng)建Person 類的子類Student
class Person(object):
pass
def __init__(self):
self.name = "Student"
# "Student" 是類名
Student = type("Student", (Person,), {"__init__": __init__})
# help() 函數(shù)用于查看函數(shù)或模塊用途的詳細(xì)說明腐泻。
print(help(Student))
運(yùn)行結(jié)果對比
元類創(chuàng)建類
class Person(object):
pass
def __init__(self):
pass
@classmethod
def test_cls_func(cls):
pass
@staticmethod
def test_static_func():
pass
Student = type(
"Student", # 類名
(Person,), # 所有的父類,使用元組傳參
{"__init__": __init__, # 實(shí)例方法
"test_cls_func": test_cls_func, # 類方法
"test_static_func": test_static_func, # 靜態(tài)方法
"type_name": "student", # 類屬性
} # 類包含的屬性
)
print(help(Student))
# 運(yùn)行結(jié)果
# {'__init__': <function __init__ at 0x0000016D93862E18>,
# 'test_cls_func': <classmethod object at 0x0000016D95716400>,
# 'test_static_func': <staticmethod object at 0x0000016D95716BA8>,
# 'type_name': 'student',
# '__module__': '__main__',
# '__doc__': None}
運(yùn)行結(jié)果
注意:
class Person(object):
pass
# Student 只是一個變量,引用了type 返回的Student類型
Student = type("Student", (Person,), {"type_name": "student", })
student = Student()
# Student2 只是一個變量,引用了type 返回的Student類型
Student2 = type("Student", (Person,), {"type_name": "student", })
student2 = Student2()
print(type(student))
print(type(student2))
# 運(yùn)行結(jié)果
# <class '__main__.Student'>
# <class '__main__.Student'>
元類改造類
元類除了能創(chuàng)建一個類,也能改造一個類.
class ChangeClass(type): # 這個必須是type子類
def __new__(cls, class_name, super_names, attrs):
print("class_name: %s" % class_name)
print("super_names: %s" % super_names)
print("attrs: %s" % attrs)
tmp_attrs = dict()
# 將所有 實(shí)例/類/靜態(tài) 方法的名字改為小寫
for key, value in attrs.items():
# hasattr(value, "__call__") 判斷值是一個func 對象,
# 不能使用isinstance , 因?yàn)?class function: # TODO not defined in builtins!(源碼)
if hasattr(value, "__call__") or isinstance(value, classmethod) or isinstance(value, staticmethod):
tmp_attrs[key.lower()] = value
continue
tmp_attrs[key] = value
return type.__new__(cls, class_name, super_names, tmp_attrs) # 一般工作中用這種方式
class Preson(object, metaclass=ChangeClass):
cls_name = "cls_name"
def __init__(self):
self.self_name = "self_name"
@classmethod
def Test_Cls_Func(cls):
pass
print("改造后 " + "*" * 20)
print(Preson.__dict__)
# 運(yùn)行結(jié)果
# class_name: Preson
# super_names: <class 'object'>
# attrs: {'__module__': '__main__', '__qualname__': 'Preson', 'cls_name': 'cls_name',
# '__init__': <function Preson.__init__ at 0x000002260B828A60>,
# 'Test_Cls_Func': <classmethod object at 0x000002260B826F28>}
# 改造后 ********************
# {'__module__': '__main__', 'cls_name': 'cls_name',
# '__init__': <function Preson.__init__ at 0x000002260B828A60>,
# 'test_cls_func': <classmethod object at 0x000002260B826F28>,
# '__dict__': <attribute '__dict__' of 'Preson' objects>,
# '__weakref__': <attribute '__weakref__' of 'Preson' objects>, '__doc__': None}
結(jié)語
經(jīng)過近兩個月的努力, 寫下了Python 學(xué)習(xí)筆記系列共計二十四篇, 限于本人精力以及能力, 篇章中如有錯誤之處, 煩請各位告知, 便于更正, 以利他人.
是結(jié)束亦是開始, 革命尚未成功, 同志仍需努力.
Html / Css / JavaScript 學(xué)習(xí) : w3school 在線教程
Python 教程 : 廖雪峰 Python 教程
菜鳥教程
到此結(jié)??DragonFangQy 2018.5.27