Raymond Hettinger <[email protected]> added the comment:
Collecting various factlets on this topic
PEP 252 gives the specification for the descriptor protocol: "__get__(): a
function callable with one or two arguments that retrieves the attribute value
from an object."
function_get, property_get, classmethod_get, and staticmethod_get all support
calls with one or two arguments:
>>> a = A()
>>> class A:
def m(self):
return 42
@property
def p(self):
return 43
@classmethod
def c(cls):
return 44
@staticmethod
def s():
return 45
>>> a = A()
>>> vars(A)['m'].__get__(a)()
42
>>> vars(A)['m'].__get__(a, A)()
42
>>> vars(A)['p'].__get__(a)
43
>>> vars(A)['p'].__get__(a, A)
43
>>> vars(A)['c'].__get__(a)()
44
>>> vars(A)['c'].__get__(a, A)()
44
>>> vars(A)['s'].__get__(a)()
45
>>> vars(A)['s'].__get__(a, A)()
45
Python functions that comply with the specification should also do the same (as
taught by the descriptor HOWTO). That said, I have found multiple Python
functions that aren't providing the None default. I will fix those as I find
them.
type.__getattribute__, object.__getattribute__ and super.__getattribute__
always call __get__ with both attributes specified:
>>> class D:
def __get__(*args):
print(args)
>>> class C:
d = D()
>>> class S(C):
def f(self):
return super().d
>>> C.d
(<__main__.D object at 0x104d967f0>, None, <class '__main__.C'>)
>>> C().d
(<__main__.D object at 0x104d967f0>, <__main__.C object at 0x104df77c0>,
<class '__main__.C'>)
>>> S().f()
(<__main__.D object at 0x104d967f0>, <__main__.S object at 0x104df7580>,
<class '__main__.S'>
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue36743>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com