В Python каждый объект имеет одно пространство имен - «атрибуты» объекта, доступные в этом пространстве имен, могут быть методами, простыми ссылками на другие объекты (вызываемыми или нет) или синтезироваться на пролететь мимо дескрипторов (обычные атрибуты могут жить в экземпляре или в классе, но дескрипторы - включая функции как дескрипторы, которые синтезируют методы - используются, только если они живут в классе, а не в экземпляре; в частности, «специальные методы» являются специальными, только если они определены в классе, а не в экземпляре). Встроенные функции обработки атрибутов и специальные методы (getattr
, setattr
, __getattr__
, __setattr__
, ...) одинаково работают в одном пространстве имен объекта, независимо от того, ссылаются ли они на «простые атрибуты» или нет .
Ключевым моментом является то, что для любого объекта a
в Python a.b
может быть методом (или другим вызываемым) или нет: компилятор Python не знает (и не заботится), вы можете взять ссылку a.b
и (например) передать его в качестве аргумента, вернуть его в качестве результата, добавить его в список и т. Д., Ни одна из этих операций не предполагает вызова a.b
. Если и когда вы хотите (попробуйте и) вызвать a.b
, вы сделаете это явно, добавив круглые скобки: a.b()
, если вы хотите вызвать его без аргументов.
В Ruby методы и атрибуты объекта находятся в отдельных пространствах имен (так что вы можете иметь объект с методом и атрибутом с тем же именем, чего в Python вы не можете) и «просто упомянуть» аргумент. Метод less вызывает его неявно (так что c=a.b
может просто принимать ссылку на атрибут или он может вызывать a.b()
; если b
называет метод и атрибут в a
, я не помню, что за эвристика правило используется для устранения неоднозначности использования). Поэтому, если вы хотите просто взять ссылки на методы (например, сохранить в некотором контейнере или использовать в качестве аргументов или возвращаемых значений), а затем выполнить вызов, вы используете другой синтаксис.
Smalltalk также имеет отдельные пространства имен, такие как Ruby, но тогда вы не можете ссылаться на атрибуты «не-метода» данного объекта (каждый объект только «видит» свои собственные атрибуты), поэтому эта двусмысленность не возникает (но вы по-прежнему приходится использовать конкретные сообщения для извлечения и последующего вызова «ссылки на метод»).