Lubię oglądać to zachowanie od "oddolnego".
Funkcja w języku Python działa jako "descriptor object". Jako taki ma on metodę __get__()
.
Dostęp do odczytu do atrybutu klasy, który ma taką metodę __get__()
, jest przekierowywany do tej metody. Dostęp do atrybutu do klasy jest wykonywany jako attribute.__get__(None, containing_class)
, podczas gdy atrybut dostępu do instancji jest mapowany na attribute.__get__(instance, containing_class)
.
Zadaniem metody z funkcji jest zawijanie funkcji w obiekcie metody, który owija parametr self
- dla przypadku dostępu do atrybutu do instancji. Nazywa się to metodą związaną.
W przypadku dostępu do atrybutu klasy w wersji 2.x funkcja __get__()
zwraca niezwiązane opakowanie metody, a jako learned today na 3.x zwraca wartość. (Zauważ, że mechanizm __get__()
nadal istnieje w 3.x, ale funkcja właśnie się zwraca.) To prawie to samo, jeśli spojrzysz na to, jak jest wywoływany, ale niezwiązane opakowanie metody sprawdza dodatkowo poprawny typ argumentu self
.
Wywołanie tworzy obiekt, którego wywołanie __get__()
ma na celu zwrócenie pierwotnie podanego obiektu, aby cofnąć opisane zachowanie. Tak działa HYRY's trick: atrybut umożliwia cofnięcie pakowania staticmethod()
, wywołanie robi to ponownie, tak że atrybut "nowy" ma taki sam status jak stary, chociaż w tym przypadku wydaje się, że staticmethod()
został zastosowany dwukrotnie (ale tak naprawdę nie jest " t).
(BTW: To działa nawet w tym dziwnym kontekście.
s = staticmethod(8)
t = s.__get__(None, 2) # gives 8
chociaż 8
nie jest funkcją i 2
nie jest klasą)
w swoim pytaniu, masz dwie sytuacje:
cmd = Cmd.cmdOne
cmd() # works fine
dostęp klasę i prosi o jego atrybutem cmdOne
, a staticmethod()
obiektu. Jest to sprawdzane poprzez jego __get__()
i zwraca pierwotną funkcję, która jest następnie wywoływana. Właśnie dlatego działa dobrze.
robi to samo, ale następnie przypisuje tę funkcję do Cmd.cmd
. Następny wiersz to dostęp do atrybutu - który ponownie wywołuje funkcję __get__()
i zwraca w ten sposób niezwiązaną metodę, która musi zostać wywołana z poprawnym obiektem self
jako pierwszym argumentem.
Nie odpowiada na pytanie. – martineau