2011-09-20 6 views
5

wiem, jeśli chcesz dodać metodę do instancji klasy nie można zrobić proste zadanie takiego:python3: metoda wiązania do instancji klasy z .__ get __(), działa tylko dlaczego?

>>> def print_var(self): # method to be added 
     print(self.var) 
>>> class MyClass: 
     var = 5 
>>> c = MyClass() 
>>> c.print_var = print_var 

rzeczywiście Spowodowałoby print_var zachowywać się jak normalne funkcjonowanie, więc self argumentem wouldn „t mają swoje typowe znaczenie:

>>> c.print_var 
<function print_var at 0x98e86ec> 
>>> c.print_var() 
Traceback (most recent call last): 
    File "<pyshell#149>", line 1, in <module> 
    c.print_var() 
TypeError: print_var() takes exactly 1 argument (0 given) 

aby umożliwić funkcję być traktowana jako metoda (czyli do wiązania go na przykład), kiedyś użyć tego kodu:

>>> import types 
>>> c.print_var = types.MethodType(print_var, c) 
>>> c.print_var 
<bound method MyClass.print_var of <__main__.MyClass object at 0x98a1bac>> 
>>> c.print_var() 
5 

ale stwierdziliśmy, że .__get__ mogą być również stosowane do tego celu:

>>> c.print_var = print_var.__get__(c) 
>>> c.print_var 
<bound method MyClass.print_var of <__main__.MyClass object at 0x98a1bac>> 
>>> c.print_var() 
5 

Problem polega na tym, że po prostu działa, ale nie mogę zrozumieć, jak i dlaczego. Dokumentacja o numerze .__get__ nie wydaje się bardzo pomocna.

Byłbym wdzięczny, gdyby ktoś mógł wyjaśnić to zachowanie interpretera Pythona.

Odpowiedz

5

Informacje szukasz jest w Descriptor HowTo Guide:

Aby obsługiwać połączenia metody, funkcje obejmują metodę __get__() do wiązania metod podczas dostępu atrybutu. Oznacza to, że wszystkie funkcje są deskryptorami niebędącymi danymi, które zwracają powiązane lub niezwiązane metody w zależności od tego, czy są one wywoływane z obiektu czy klasy. W czystym Pythonie, to działa tak:

class Function(object): 
    . . . 
    def __get__(self, obj, objtype=None): 
     "Simulate func_descr_get() in Objects/funcobject.c" 
     return types.MethodType(self, obj, objtype) 

Więc tak naprawdę nie ma nic dziwnego dzieje - metoda obiektu funkcyjnego __get__ wzywa types.MethodType i zwraca wynik.

+1

W języku Python 3 'MethodType()' akceptuje tylko 2 argumenty. – joeforker

+0

@joeforker Cytuję z dokumentów Pythona, brzmi, jakby trzeba było je zaktualizować. – agf

Powiązane problemy