首页 > 代码库 > python中类的内置属性初探

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>)
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>>)  # 用@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中类的内置属性初探