Основываясь на моем понимании модели данных 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, если это имеет значение.