python中類的內置屬性初探
阿新 • • 發佈:2017-08-08
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‘>)object內置屬性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>)
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中類的內置屬性初探