Dlaczego Python zmienia wolną funkcję w niezwiązaną metodę po przypisaniu do zmiennej klasy?
def make_func(s):
def func(x):
return '%s-%d' % (s, x)
return func
class Foo(object):
foofunc = make_func('foo')
Więc to działa zgodnie z oczekiwaniami: (zwraca "Dog-1")
make_func('dog')(1)
Ale to się nie powiedzie:
Foo.foofunc(1)
TypeError: unbound method func() must be called with Foo instance as first argument (got int instance instead)
Po bliższej inspekcji Python zmienił "wewnętrzna" funkcja func
wewnątrz make_func
do metody, ale ponieważ nie ma self
, ta metoda nigdy nie zadziała. Dlaczego Python to robi?
>>> import inspect
>>> inspect.getmembers(Foo, inspect.ismethod)
[('foofunc', <unbound method Foo.func>)]
2 odpowiedzi
Python nie może powiedzieć "jak" przypisywałeś metodę atrybutu klasy. Nie ma różnicy między tym:
class Foo(object):
def meth():
pass
I to
def func():
pass
class Foo(object):
meth = func
W obu przypadkach wynik jest taki, że obiekt funkcji jest przypisany do atrybutu klasy o nazwie 'meth'
. Python nie może powiedzieć, czy przypisałeś go, definiując funkcję w klasie lub "ręcznie" przypisując go za pomocą meth = func
. Może zobaczyć tylko "wynik końcowy", który jest atrybutem, którego wartość jest funkcją. Tak czy inaczej, gdy funkcja jest w klasie, jest ona konwertowana na metodę za pomocą normalnego procesu, który powiadamia funkcje w definicjach klas i czyni je metodami.
class Foo(object):
foofunc = make_func('foo')
Foofunc jest zmienną klasową, a nie metodą (dla której potrzebujesz "def"). I zainicjuj go z wynikiem make_func (...), więc nie zmieni się ponownie.
Jeśli chcesz zadzwonić foo.foofon, musisz przypisać foofunc = make_func
bez parametru.
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.