ITEEDU

实例属性和类属性

Python Class 同样包含类型和实例两种成员。

>>> class Class1:
    i = 123 # Class Field
    def __init__(self):
        self.i = 12345 # Instance Field
        
>>> print Class1.i
123
>>> print Class1().i
12345

两个比较重要的取实例属性的函数:

getattr(实例,属性名),hasattr(实例,属性名)判断属性名是否属于实例。

如上例:s='i',getattr(Class1(),s)=12345

hasattr(Class1(),s)=True

用实例访问时会有隐藏类变量的可能,因为变量搜索顺序为先实例后类。

>>> class Class1:
    i = 123
    def __init__(self):
        print self.i 
        print hex(id(self.i))

>>> hex(id(Class1.i)) # 显示 Class1.i
'0xab57a0'
>>> a = Class1() # 创建 Class1 实例,我们会发现 self.i 实际指向 Class1.i。
123
0xab57a0
>>> Class1.__dict__ # 显示 Class1 成员
{'i': 123, '__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x00D39470>}
>>> a.__dict__ # 显示实例成员
{}
>>> a.i = 123456789 # 为实例新增一个成员 i
>>> hex(id(a.i)) # 显示新增实例成员地址
'0xbbb674'
>>> a.__dict__ # 显示实例成员
{'i': 123456789}

如果是可变的类属性的话,就不会隐藏类属性,而是直接修改类属性。

class MyClass:
    x = {'num': 1}

mc = MyClass()
print mc.x                  # {'num': 1}
mc.x['price']=200
print mc.x                  # {'price': 200, 'num': 1}

Class 有一些特殊的属性,便于我们获得一些额外的信息。

>>> class Class1(object):
    """Class1 Doc."""
    def __init__(self):
        self.i = 1234

>>> Class1.__doc__ # 类型帮助信息
'Class1 Doc.'
>>> Class1.__name__ # 类型名称
'Class1'
>>> Class1.__module__ # 类型所在模块
'__main__'
>>> Class1.__bases__ # 类型所继承的基类
(<type 'object'>,)
>>> Class1.__dict__ # 类型字典,存储所有类型成员信息。
<dictproxy object at 0x00D3AD70>
>>> Class1().__class__ # 类型
<class '__main__.Class1'>
>>> Class1().__module__ # 实例类型所在模块
'__main__'
>>> Class1().__dict__ # 对象字典,存储所有实例成员信息。
{'i': 1234}