Основываясь на моем понимании модели данных Python и, в частности, подраздела «Методы экземпляра», всякий раз, когда вы читаете атрибут, значение которого имеет тип «пользовательская функция», возникает некоторая магия, и выполучить связанный экземплярный метод вместо действительной, исходной функции.Эта магия заключается в том, что вы не передаете явно параметр self
при вызове метода.
Но тогда я бы ожидал, что смогу заменить метод объекта функцией с такой же сигнатурой:
class Scriptable:
def __init__(self, script = None):
if script is not None:
self.script = script # replace the method
def script(self):
print("greetings from the default script")
>>> scriptable = Scriptable()
>>> scriptable.script()
greetings from the default script
>>> def my_script(self):
... print("greetings from my custom script")
...
>>> scriptable = Scriptable(my_script)
>>> scriptable.script()
Traceback (most recent call last):
...
TypeError: script() takes exactly 1 positional argument (0 given)
Я создаю экземпляр Scriptable
и устанавливаю его атрибут script
для пользовательской функции с одним параметром, точно так же, как это определено в классе.Поэтому, когда я читаю атрибут scriptable.script
, я ожидаю, что магия включится и даст мне метод привязанного экземпляра, который не принимает параметров (так же, как я получаю, когда я не заменил script
).Вместо этого он, похоже, возвращает ту же самую функцию, которую я передал, параметр self
и все.Магия привязки метода не происходит.
Почему магия привязки метода работает, когда я определяю метод внутри объявления класса, а не когда я присваиваю атрибут?Что заставляет Python по-разному относиться к этим ситуациям?
Я использую Python3, если это имеет какое-то значение.