Skip to content

Latest commit

 

History

History
79 lines (64 loc) · 2.13 KB

object_oriented17.md

File metadata and controls

79 lines (64 loc) · 2.13 KB

属性访问方式的总结

我们在最近6篇文章中介绍了Python中类的属性访问的相关内容,本篇文章为大家进行一个总结。

属性是类中最基本的单元,任何一个定义在类中的元素都是属性。通常,属性会存储在所处作用域的__dict__特殊属性中。例如,实例的属性存储于实例的__dict__,而类属性存储于类的__dict__中。

class A:
    cls_a = 1
    def __init__(self):
        self.obj_a = 2
        
a = A()
print(a.__dict__)
# {'obj_a': 2}
print(A.__dict__)
# {'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__init__': <function A.__init__ at 0x0000029EB4A34048>, '__doc__': None, 'cls_a': 1, '__weakref__': <attribute '__weakref__' of 'A' objects>}

访问属性通常有三种方式:点运算符,直接访问__dict__中的字典项,getattr()方法。

print(a.obj_a)
print(getattr(a, 'obj_a'))
print(a.__dict__['obj_a'])

# 2
# 2
# 2

另一种比较特殊的访问方式是利用中括号访问,这多存在于各种数据类型中:

dic = {
    'a': 1,
    'b': 'c'
}
lst = [1, 2, 3]
print(dic['a'])
# 1
print(lst[0])
# 1

这种访问方式是通过__getitem__协议支持的。实现了__getitem__协议的类可以利用中括号访问属性:

class GetItem:
    def __getitem__(self, key):
        if key == 'a':
        	return 1
        else:
            return 2
g = GetItem()
print(g['a'])
# 1
print(g[0])
# 2

在Python中,属性的访问(不包括__getitem__)由__getattribute__特殊方法控制。该方法在基类object中利用C语言实现,如果用户没有覆盖这个方法,那么类的属性访问将会调用object中的__getattribute__完成:

class A:
    cls_a = 1
    def __init__(self):
        self.obj_a = 2
    def __getattribute__(self, name):
        print('In __getattribute__ Class A')
        return object.__getattribute__(self, name)
    
a = A()
print(a.obj_a)
# 'In __getattribute__ Class A'
# 2

__getattribute__