Atribuindo uma função a um atributo de objeto

Com base no meu entendimento de Modelo de dados do Python e, especificamente, a subseção "Métodos da instância", sempre que você ler um atributo cujo valor é do tipo "função definida pelo usuário", alguma mágica entra em ação e você obtém um método de instância vinculado em vez da função real e original. Essa mágica é a razão pela qual você não passa explicitamente oself quando você está chamando um métod

Mas, esperaria poder substituir o método de um objeto por uma função com a mesma assinatura:

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)

Estou criando uma instância deScriptable e definindo seuscript atribui a uma função definida pelo usuário com um único parâmetro, exatamente como o definido na classe. Então, quando eu li oscriptable.script, eu esperaria que a mágica surgisse e me desse um método de instância vinculada que não use parâmetros (assim como eu recebo quando não substituiscript). Em vez disso, parece estar devolvendo exatamente a mesma função que passei,self parâmetro e tudo. A mágica de ligação de método não está acontecendo.

Por que a mágica de ligação de método funciona quando eu defino um método dentro da declaração de classe, mas não quando atribuo o atributo? O que faz o Python tratar essas situações de maneira diferente?

Estou usando Python3 se faz alguma diferenç

questionAnswers(4)

yourAnswerToTheQuestion