1. 程式人生 > >python中類的內置屬性初探

python中類的內置屬性初探

fad group ros one ref for wrapper div 類與對象

首先,建立一個類,並用該類創建一個對象,分別查看object,類與對象的內置屬性

技術分享
 1 import inspect
 2 
 3 class Foo():
 4     ‘‘‘隨便瞎寫‘‘‘
 5     group = buluo     # 類屬性
 6 
 7     @classmethod
 8     def getnum(cls):    # 類方法
 9         return 123
10 
11     def __init__(self):
12         self.name = 222   # 對象私有屬性
13         self.age = 12
14
15 def changeName(self): # 對象綁定方法 16 self.name = self.__class__.getnum() 17 18 # 創建類,並獲取三者內置屬性 19 a = Foo(); 20 inspect.getmembers(object): 21 inspect.getmembers(Foo): 22 inspect.getmembers(a):
實例類 技術分享
 1 # slot wrapper "插口"包裝,繼承object類之後進行重寫,
 2 
 3 (__class__, <class type>)
4 (__delattr__, <slot wrapper __delattr__ of object objects>) 5 (__dir__, <method __dir__ of object objects>) 6 (__doc__, The most base type) 7 (__eq__, <slot wrapper __eq__ of object objects>) 8 (__format__, <method __format__ of object objects>)
9 (__ge__, <slot wrapper __ge__ of object objects>) 10 (__getattribute__, <slot wrapper __getattribute__ of object objects>) 11 (__gt__, <slot wrapper __gt__ of object objects>) 12 (__hash__, <slot wrapper __hash__ of object objects>) 13 (__init__, <slot wrapper __init__ of object objects>) 14 (__init_subclass__, <built-in method __init_subclass__ of type object at 0x1DFFADB8>) 15 (__le__, <slot wrapper __le__ of object objects>) 16 (__lt__, <slot wrapper __lt__ of object objects>) 17 (__ne__, <slot wrapper __ne__ of object objects>) 18 (__new__, <built-in method __new__ of type object at 0x1DFFADB8>) 19 (__reduce__, <method __reduce__ of object objects>) 20 (__reduce_ex__, <method __reduce_ex__ of object objects>) 21 (__repr__, <slot wrapper __repr__ of object objects>) 22 (__setattr__, <slot wrapper __setattr__ of object objects>) 23 (__sizeof__, <method __sizeof__ of object objects>) 24 (__str__, <slot wrapper __str__ of object objects>) 25 (__subclasshook__, <built-in method __subclasshook__ of type object at 0x1DFFADB8>)
object內置屬性

Foo類的內置屬性,去掉object重復的,可以看到,多了一個__dict__以及其他方法與屬性

(__class__, <class type>)
(__dict__, mappingproxy({__module__: __main__, __doc__: 隨便瞎寫, group: buluo, getnum: <classmethod object at 0x02237770>, __init__: <function Foo.__init__ at 0x022BA078>, changeName: <function Foo.changeName at 0x022BA0C0>, __dict__: <attribute __dict__ of Foo objects>, __weakref__: <attribute __weakref__ of Foo objects>}))
(__doc__, 隨便瞎寫)
(changeName, <function Foo.changeName at 0x022BA0C0>)  # 對於類來說,changeName為類的普通方法
(getnum, <bound method Foo.getnum of <class __main__.Foo>>)  # [email protected]
(group, buluo)

Foo對象的內置屬性

(__class__, <class __main__.Foo>)
(__dict__, {name: 222, age: 12})  # 對象的__dict__ 只包含私有的屬性

# 類的靜態方法或者方法,對於對象來說,都為綁定方法,綁定對象不同,一個是Foo object,一個是class.__main__.Foo
(changeName, <bound method Foo.changeName of <__main__.Foo object at 0x02242390>>)  
(getnum, <bound method Foo.getnum of <class __main__.Foo>>)

(group, buluo)
(name, 222) 
(age, 12)

總結:1.__dict__為對象的私有屬性,對對象來說,則為私有變量(方法並非私有,而是綁定),

                 對元類的對象(即metaclass為type的類),則為__module__,__doc__,屬性、方法以及一個弱引用

   2.對象的私有屬性不單單會在__dict__中出現,在對象的內置屬性內也會存在,而__dict__的存在為了加快處理速度,屏蔽其他不需要註意的屬性

----------------------------------------------------------------------------------------------------分割線----------------------------------------------------------------------------------------------------------------------

疑問:私有屬性在__dict__以及內置屬性中都出現,對象的大量創建會導致內存壓力,如何解決,使用__slots__

通過__slots__將屬性固定

技術分享
 1 class Foo_slot():
 2     group = buluo
 3     __slots__ = [name, age]
 4 
 5     @classmethod
 6     def getnum(cls):    # 類方法
 7         return 123
 8 
 9     def changeName(self):   # 對象綁定方法
10         self.age = self.__class__.getnum()
測試類

帶有__slots__Foo類的內置屬性,__dict__不存在

(__slots__, [name, age])

# __slots__中的變量,類型為member,“成員”,類似C中的結構體
(age, <member age of Foo_slot objects>)
(name, <member name of Foo_slot objects>)

(group, buluo)    # 類的普通變量不變

# 方法不受影響
(changeName, <function Foo_slot.changeName at 0x01F0D150>)
(getnum, <bound method Foo_slot.getnum of <class __main__.Foo_slot>>)

帶有__slots__Foo類的對象的內置屬性

(__slots__, [name, age]) # 與普通類不同,在內置屬性中並未帶有屬性,請查看上面“Foo對象的內置屬性”中,包含了屬性以及屬性值

(changeName, <bound method Foo_slot.changeName of <__main__.Foo_slot object at 0x021B23F0>>)
(getnum, <bound method Foo_slot.getnum of <class __main__.Foo_slot>>)

(group, buluo)    # 類的屬性不受影響
# 除了類的屬性之外,私有屬性並沒有在對象的內置屬性中出現,可見slots的類,去掉__dict__與私有方法,確實在內存中會節省一部分空間

python中類的內置屬性初探