__get__()方法研究

看源码的时候发现了这个魔法方法

 1 class A(object):
 2     def __init__(self):
 3         self.name = 'mod'
 4 
 5     def __get__(self, instance, owner):
 6         print(instance, '=====', owner)
 7         return self
 8 
 9 
10 class B(object):
11     a = A()
12 
13 
14 class C(object):
15     d = A()
16 
17     def __init__(self):
18         self.a = A()
19 
20 
21 b = B()
22 c = C()
23 
24 print(B.a)
25 # None ===== <class '__main__.B'>
26 # <__main__.A object at 0x7f0485e519b0>
27 
28 print(b.a)
29 # <__main__.B object at 0x7f0484825b70> ===== <class '__main__.B'>
30 # <__main__.A object at 0x7f0485e519b0>
31 
32 print(b.a.name)
33 # <__main__.B object at 0x7f0484825b70> ===== <class '__main__.B'>
34 # mod
35 
36 print(c.a)
37 # <__main__.A object at 0x7f0485e33208>
38 
39 print(c.d)
40 # _main__.C object at 0x7f0484825b38> ===== <class '__main__.C'>
41 # <__main__.A object at 0x7f0484825c18>

依次总结:

第一次打印,通过类调用类属性,打印结果,instance为None,可以理解, get方法的第一个参数为调用该方法的实例,第二个为该实例所属的类

第二次打印,通过实例调用类属性,打印结果印证了上面的结论

第三次打印,仅证明该属性正常可用

第四次打印,通过实例调用作为实例属性的A(),结果发现没有触发__get__方法,说明__get__方法仅仅是作为类属性的时候才会被触发

第五次打印,证明以上结论

另外,__get__方法必须带有两个参数,这是被调用时强制携带的,不然会报错如下:

TypeError: __get__() takes 2 positional arguments but 3 were given

那么这个方法有啥用处呢,其实玩法还挺多的,我能想到的一个就是可以限制别的类乱调用.比如判断将该类定为类属性的类是不是我们期望的类,如果不是,那就返回空.

猜你喜欢

转载自www.cnblogs.com/haiton/p/11026934.html