python中类的内置属性初探
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中类的内置属性初探相关的知识,希望对你有一定的参考价值。
首先,建立一个类,并用该类创建一个对象,分别查看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>)
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‘>>) # 用@staticmethod装饰器的getnum函数为类的绑定方法 (‘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中类的内置属性初探的主要内容,如果未能解决你的问题,请参考以下文章