Python 類中,凡是以雙下劃線 "__" 開頭和結(jié)尾命名的成員(屬性和方法),這些特殊成員存在著一些特殊含義,都被稱為類的特殊成員(特殊屬性和特殊方法)。
我們把特殊屬性也可以稱之為魔法屬性,或者內(nèi)置類屬性。
1、__name__屬性
__name__是用來標識模塊名字的一個系統(tǒng)變量。
這里分兩種情況:
- 第一種情況指的是當前運行的模塊,那么當前模塊
__name__的值就為__main__。 - 第二種情況指的是該模塊是使用
import導(dǎo)入的模塊,那么這個被導(dǎo)入模塊的__name__變量的值為該模塊的文件名(去掉.py)。
示例:
Demo1.py文件
# 在當前文件中直接調(diào)用__name__屬性
def my_func():
print("我的模塊名是", __name__)
# __name__屬性在模塊中可直接調(diào)用
# 在當期模塊中調(diào)用
# 結(jié)果:我的模塊名是 __main__
if __name__ == "__main__":
my_func()
Demo2.py文件
# 導(dǎo)入Demo1模塊,使用模塊中的my_func()方法
from Demo1 import *
# 執(zhí)行my_func()方法
# 結(jié)果:我的模塊名是 Demo1
my_func()
2、__bases__屬性
Python 為所有類都提供了一個__bases__屬性,通過該屬性可以查看該類的所有直接父類,該屬性返回所有直接父類組成的元組。(直接父類)
class A(object):
pass
class B(A):
pass
class C(B):
pass
class D(C,B,A):
pass
# 類名直接調(diào)用__bases__屬性
print(C.__bases__)
print(D.__bases__)
"""
輸出結(jié)果:
(<class '__main__.B'>,)
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>)
"""
注意:在類的實例對象中沒有
__bases__屬性。
3、__mro__屬性
Python的每一個有父類的類,都有一個與方法解析順序相關(guān)的特殊屬性__mro__屬性, 它是一個tuple(元組), 裝著方法解析時的對象查找順序,越靠前的優(yōu)先級越高。
執(zhí)行下面的代碼:
class A(object):
pass
class B(A):
pass
class C(B):
pass
# 類名直接調(diào)用__bases__屬性
print(C.__bases__)
print(C.__mro__)
"""
輸出結(jié)果:
(<class '__main__.B'>,)
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
"""
__mro__屬性和__bases__屬性的區(qū)別
__bases__屬性是查看當前類的直接父類,返回一個元組。
__mro__屬性是指在有繼承關(guān)系中,包括單繼承,多重繼承,多層繼承中。使用super調(diào)用父類的方法和屬性的時候,優(yōu)先查找的順序。
4、__doc__屬性
作用:表示類的描述文檔信息。
class Person:
"""
這里是類的描述類信息。
"""
def func(self):
"""
這里是類中方法的描述類信息。
"""
pass
# 因為是屬性,不用加()
print(Person.__doc__)
輸出結(jié)果:

5、__module__和__class__屬性
__module__屬性:表示當前操作的對象屬于哪個模塊。
__class__屬相:表示當前操作的對象的是由哪個類創(chuàng)建的。
# 定義一個類
class Person(object):
pass
obj = Person()
print(obj.__module__)
print(obj.__class__)
"""
輸出結(jié)果:
__main__ : 表示前擋模塊
<class '__main__.Person'> : 表示該對象屬于當前模塊中的Python類
"""
6、__dict__屬性
列出類中或者對象中的所有成員,以字典的形式返回。這個屬性不用我們再類中覆寫,類和對象默認自帶。
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def tellMe(self):
print(f'我叫{self.name},今年{self.age}')
# 獲取類的所有成員
print(Person.__dict__)
# # 獲取對象的所有成員
obj1 = Person('美猴王', "18")
obj2 = Person('齊天大圣', "30")
print(obj1.__dict__)
print(obj2.__dict__)
"""
輸出結(jié)果 :
類的所有成員:
{'__module__': '__main__',
'__init__': <function Person.__init__ at 0x0000000002425828>,
'tellMe': <function Person.tellMe at 0x0000000002425A68>,
'__dict__': <attribute '__dict__' of 'Person' objects>,
'__weakref__': <attribute '__weakref__' of 'Person' objects>,
'__doc__': None}
注意:__weakref__,和垃圾回收機制,還有弱引用的知識點有關(guān)。
對象的所有成員:
{'name': '美猴王', 'age': '18'}
{'name': '齊天大圣', 'age': '30'}
"""
注意:從上面的結(jié)果可以看出,對象調(diào)用
__dict__屬性,沒有看到對象中的方法。
- 類的實例屬性屬于對象,類的實例方法不屬于對象。也就是說
__dict__屬性不打印處對象的中方法。- 類中的類屬性和方法等都屬于類。
7、__slots__屬性
Python是動態(tài)語言,對于普通的類,可以為類的實例對象賦值任何屬性,這些屬性會存儲在__dict__中。
而類中定義了__slots__屬性,它僅允許動態(tài)綁定__slots__里邊定義的屬性。
示例:
# 創(chuàng)建一個Student類
class Student():
# 定義__slots__
__slots__ = ('name', 'age')
# 創(chuàng)建一個學(xué)生對象
stu = Student()
# 動態(tài)添加__slots__屬性中定義的屬性,可以添加
stu.name = '孫悟空'
stu.age = 18
# 而__slots__屬性中沒有定義的屬性,是添加不了的。
# 結(jié)果:AttributeError: 'Student' object has no attribute 'addr'
stu.addr = "北京"