Na podstawie mojego zrozumienia Python's data model, a szczególnie podsekcji "Metody instancji", za każdym razem, gdy czytasz atrybut, którego wartość jest typu "funkcja zdefiniowana przez użytkownika", niektóre magiczne kopnięcia i otrzymujesz metoda związanej instancji zamiast faktycznej, oryginalnej funkcji. Ta magia powoduje, że podczas wywoływania metody nie przekazujesz jawnie parametru self
.Przypisywanie funkcji do atrybutu obiektu
Ale potem, będę oczekiwać, aby móc zastąpić metodę wykonania obiektu z funkcji z tym samym podpisem:
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)
tworzę instancję Scriptable
i ustawienie jego atrybut script
użytkownikowi -definiowana funkcja z pojedynczym parametrem, podobnie jak zdefiniowano w klasie. Więc kiedy przeczytałem atrybut scriptable.script
, oczekiwałbym, że magia się pojawi i poda mi metodę związaną z instancją, która nie przyjmuje parametrów (tak jak ja, kiedy nie zastąpiłem script
). Zamiast tego wydaje się, że oddaje dokładnie tę samą funkcję, którą przekazałem, parametr self
i wszystko. Magia wiążąca metody nie dzieje się.
Dlaczego magia wiążąca metody działa, gdy definiuję metodę wewnątrz deklaracji klasy, ale nie wtedy, gdy przypisuję atrybut? Co sprawia, że Python traktuje te sytuacje inaczej?
Używam Python3, jeśli robi różnicę.
Podobnie jak w przypadku większości magii, został zaprojektowany, aby zrobić dokładnie tak, jakbym się tego prawa: „Ważne jest również, aby pamiętać, że funkcje zdefiniowane przez użytkownika które są ** atrybutami instancji klasy ** są ** nie ** konwertowane na metody związane, a dzieje się tak tylko wtedy, gdy funkcja jest atrybutem ** klasy **. " Za pomocą instrukcji "self.script" tworzysz atrybut instancji. Statyczna metoda "Scriptable.script" nadal istnieje. Możliwym obejściem byłoby wywołanie twojego wstrzykniętego 'script' w poprzedniej metodzie' script'. –