z.bar
- это метод bound - он уже имеет атрибут im_self
, который становится первым аргументом (условно названным self
) для базового объекта функции, im_func
привязанного метода приписывать. Чтобы переопределить это, вам, очевидно, нужно повторно связать im_self
( edit : или вместо этого вызвать im_func
) - что бы вы ни делали с точки зрения передачи аргументов, это никак не повлияет на это, конечно. Да, это документированный способ привязанных методов , работающий в Python (не просто деталь реализации: каждая правильная реализация Python должна делать это именно так). Таким образом, это «необходимо» в том смысле, что оно является частью того, что делает Python именно тем языком, которым он является, в отличие от того, чтобы быть немного или сильно отличным языком. Конечно, вы можете разработать другой язык, который будет играть по совершенно другим правилам, но - конечно, это не будет Python.
Редактировать : правки ОП разъяснили, что он вызывает несвязанный метод, а не связанный метод. Это все еще не работает, и причина ясна из сообщения об ошибке, которое пытается получить:
TypeError: метод unbound bar () должен
вызываться с экземпляром Foo первым
аргумент (вместо этого ничего не получил)
Правило, лежащее в основе этого очень четкого сообщения об ошибке, состоит в том, что экземпляр должен быть первым аргументом (поэтому, конечно, позиционный: именованные аргументы не имеют порядка). Несвязанный метод не «знает» (и не заботится), каким может быть имя этого параметра (и использование имени self
для него - всего лишь соглашение , не правило языка Python): его заботит только однозначное условие «первого аргумента» (среди позиционных, конечно).
Этот непонятный угловой случай, безусловно, может быть изменен (с помощью патча Python 3.2, если и когда изменение языка закончится, «заморозить» ;-), сделав несвязанные методы серьезно более сложными: им придется проанализировать и сохранить первый -argument name во время создания и проверять аргументы ключевых слов при каждом вызове на случай, если кто-то передаст self
по имени, а не по позиции. Я не думаю, что это сломало бы любой существующий, работающий код, это только замедлило бы почти каждую существующую программу Python. Если вы напишите и предложите патч, реализующий эту сложность, и станете активными на python-dev, чтобы защищать его от неизбежной огненной бури противодействия, у вас, без сомнения, будет шанс> 0 пробить его - удачи .
Тем временем остальные из нас будут продолжать получать атрибут im_func
, как один абсурдно крошечный дополнительный шаг в том, что должно быть довольно сложным встроенным зданием метапрограммирования, чтобы оправдать такое изменение - это не так. вообще «особый случай», по сравнению с ужасными трудностями адаптации передачи именованных аргументов к встроенным , которые не принимают именованных аргументов (и не раскрывают их) имен аргументов «легко разрешить преобразование именованных аргументов в позиционные (теперь , на которые будет стоить атаковать ветряная мельница, ИМХО: из всех вызываемых, встроенные являются наихудшими для метапрограммы, из-за этого! 1046 *