Avete ragione a mettere in discussione la documentazione. Ho provato a cercare attraverso CPython sources per trovare una spiegazione, ma attenzione: non sono esperto.
Dalla mia comprensione, attributo di ricerca e descrittore __get__
invocazione si verifica in instance_getattr2
(estratti scelti):
v = class_lookup(inst->in_class, name, &klass);
if (v != NULL) {
f = TP_DESCR_GET(v->ob_type);
if (f != NULL) {
PyObject *w = f(v, (PyObject *)inst, (PyObject *)(inst->in_class));
}
}
Quindi, o mi manca qualcosa, o niente per l'attuazione richiede un nuovo oggetto-style (che contraddice la documentazione).
Per la cronaca, ho provato a ricompilare Python per limitare il richiamo del descrittore a nuovi oggetti di classi di stile, ma in realtà ha provocato un pasticcio gigantesco. Ho appreso nel processo che i metodi di classe stessi sono implementati come descrittori: questo è il meccanismo utilizzato per restituire oggetti metodo vincolati o non associati a seconda dell'utilizzo. Per esempio:
>>> class A:
... def foo():
... pass
...
>>> A.foo.__get__(None, A)
<unbound method A.foo>
>>> A.foo.__get__(A(), A)
<bound method A.foo of <__main__.A instance at 0x000000000229CC48>>
Di conseguenza, sembra che la prevenzione descrittore invocazione per gli attributi degli oggetti in stile antico o classi sarebbe anche impedire le chiamate di metodo su di loro, almeno con l'attuazione CPython.
Ancora una volta, non sono esperto e questa è la prima volta che mi tuffo nell'implementazione di Python, quindi potrei sbagliarmi. Ho archiviato an issue per cercare di chiarire questo.
Perché 'Descriptor' è una classe di nuovo stile. – martineau