Вы подняли хороший вопрос.
Вот хорошая ссылка для лучшего понимания отношений между объектами, классами и метаклассами:
Я также нахожу эту ссылку на дескрипторы довольно понятной в отношении механизма поиска в python.
Но я не могу сказать, что понимаю, почему a.foo
терпит неудачу, когда A.foo
успешен. Кажется, что когда вы ищите атрибут объекта, а python не находит его там, он не совсем ищет атрибут в классе, потому что, если это так, он найдет A.foo
.
EDIT:
Oh! Я думаю, что понял. Это связано с тем, как работает наследование. Если вы рассматриваете схему, предоставленную над ссылкой , она выглядит следующим образом:

Схематически это сводится к:
type -- object
| |
Meta -- A -- a
Переход влево означает переход в класс данного экземпляра. Переход вверх означает переход к родителю .
Теперь механизм наследования заставляет механизм поиска сделать поворот вправо в схеме выше. Это идет a → A → object
. Это должно быть сделано для того, чтобы следовать правилу наследования! Чтобы было понятно, путь поиска:
object
^
|
A <-- a
Тогда, очевидно, атрибут foo
не будет найден.
Однако при поиске атрибута foo
в A
он найден , потому что путь поиска:
type
^
|
Meta <-- A
Все это имеет смысл, когда думаешь о том, как работает наследование.