Was ist eine "Methode" in Python?

75

Kann mir bitte jemand in sehr einfachen Worten erklären, was eine "Methode" in Python ist?

In vielen Python-Tutorials für Anfänger wird dieses Wort so verwendet, als ob der Anfänger bereits wüsste, was eine Methode im Kontext von Python ist. Obwohl ich natürlich mit der allgemeinen Bedeutung dieses Wortes vertraut bin, habe ich keine Ahnung, was dieser Begriff in Python bedeutet. Erklären Sie mir bitte, worum es bei der "Pythonian" -Methode geht.

Ein sehr einfacher Beispielcode wäre sehr willkommen, da ein Bild mehr sagt als tausend Worte.

brillant
quelle
1
"viele Python-Tutorials"? Über welche spezifischen Tutorials sprechen Sie? Wir können keinen anderen empfehlen, wenn wir nicht wissen, was Sie gerade lesen.
S.Lott
5
Methode ist ein allgemeiner Begriff, er hat in Python keine andere Bedeutung, deshalb wird er wahrscheinlich so nonchalant verwendet. Siehe en.wikipedia.org/wiki/Method_(computer_science)
Jochen Ritzel
@ S.Lott: Es tut mir leid, vielleicht war ich zu absolutistisch, als ich mein Urteil über Python-Tutorials fällte.
brillanter
1
Ich beschwere mich nicht. "viele" mögen wahr sein. Aber ich stelle eine Frage. Über welche spezifischen Tutorials sprechen Sie?
S.Lott

Antworten:

85

Es ist eine Funktion, die Mitglied einer Klasse ist:

class C:
    def my_method(self):
        print("I am a C")

c = C()
c.my_method()  # Prints("I am a C")

So einfach ist das!

(Es gibt auch einige alternative Methoden, mit denen Sie die Beziehung zwischen der Klasse und der Funktion steuern können. Ich vermute jedoch aus Ihrer Frage, dass Sie nicht danach fragen, sondern nur nach den Grundlagen.)

RichieHindle
quelle
8
Hierbei ist zu beachten, dass die Instanz manuell an die Methode übergeben werden muss und gemäß Konvention als übergeben wird self.
Skilldrick
7
@Silldrick: Du meinst wahrscheinlich das Richtige, aber dein Kommentar wie er ist impliziert etwas Falsches. Die Instanz muss beim Aufrufen einer Methode nicht explizit / manuell übergeben werden. Die Methode muss sie jedoch explizit empfangen, dh Sie müssen manuell einen Parameter für die Instanz hinzufügen (der ja gemäß selfKonvention aufgerufen wird).
4
@delnan - Ja, danke für die Klarstellung - wenn ich sage, manuell übergeben, was ich wirklich meine, muss es explizit als Parameter empfangen werden, aber es wird implizit übergeben.
Skilldrick
5
@AaronMcSmooth: Die Antwort von AndiDog ist sicherlich vollständiger. Mich würde interessieren, ob @brilliant es "besser" oder zu vollständig findet. Manchmal ist eine einfache Antwort besser. (Weil ich nicht gerne beschuldigt werde, Rep-Huren zu haben, habe ich meine Antwort CW gegeben.)
RichieHindle
2
@brillant. Lassen Sie sich nicht von einer simplen Antwort verwirren. Es steckt (etwas) mehr dahinter als "eine Methode ist eine Funktion", aber der Unterschied ist absolut entscheidend. Schauen Sie sich die andere Antwort an und stellen Sie neue Fragen für alles, was Sie nicht verstehen.
Aaronasterling
41

Eine Methode ist eine Funktion, die eine Klasseninstanz als ersten Parameter verwendet. Methoden sind Mitglieder von Klassen.

class C:
    def method(self, possibly, other, arguments):
        pass # do something here

Da Sie wissen wollten, was es in Python speziell bedeutet, können Sie zwischen gebundenen und ungebundenen Methoden unterscheiden. In Python sind alle Funktionen (und damit auch Methoden) Objekte, die herumgereicht und "gespielt" werden können. Der Unterschied zwischen ungebundenen und gebundenen Methoden ist also:

1) Gebundene Methoden

# Create an instance of C and call method()
instance = C()

print instance.method # prints '<bound method C.method of <__main__.C instance at 0x00FC50F8>>'
instance.method(1, 2, 3) # normal method call

f = instance.method
f(1, 2, 3) # method call without using the variable 'instance' explicitly

Gebundene Methoden sind Methoden, die zu Instanzen einer Klasse gehören. In diesem Beispiel instance.methodist an die aufgerufene Instanz gebunden instance. Jedes Mal, wenn diese gebundene Methode aufgerufen wird, wird die Instanz automatisch als erster Parameter übergeben - was gemäß selfKonvention aufgerufen wird.

2) Ungebundene Methoden

print C.method # prints '<unbound method C.method>'
instance = C()
C.method(instance, 1, 2, 3) # this call is the same as...
f = C.method
f(instance, 1, 2, 3) # ..this one...

instance.method(1, 2, 3) # and the same as calling the bound method as you would usually do

Wenn Sie auf C.methoddie Methode innerhalb einer Klasse anstatt innerhalb einer Instanz zugreifen , erhalten Sie eine ungebundene Methode. Wenn Sie es nennen wollen, müssen Sie die Instanz als ersten Parameter übergeben , da das Verfahren nicht in jedem Fall gebunden.

Wenn Sie diesen Unterschied kennen, können Sie Funktionen / Methoden als Objekte verwenden, z. B. Methoden weitergeben. Stellen Sie sich als Beispiel für einen Anwendungsfall eine API vor, mit der Sie eine Rückruffunktion definieren können, aber eine Methode als Rückruffunktion bereitstellen möchten. Kein Problem, einfach self.myCallbackMethodals Rückruf übergeben und es wird automatisch mit der Instanz als erstem Argument aufgerufen. Dies wäre in statischen Sprachen wie C ++ (oder nur mit Tricks) nicht möglich.

Hoffe du hast den Punkt verstanden;) Ich denke das ist alles was du über Methodengrundlagen wissen solltest. Sie könnten auch mehr über die classmethodund staticmethodDekorateure lesen , aber das ist ein anderes Thema.

AndiDog
quelle
Super interessant, danke für die Erklärung. Scheint eine ungewöhnlich aggressive Konvention für Python zu sein (um alle nachfolgenden Argumente zu verschieben, wenn es mit Punktnotation auf einer Klasseninstanz aufgerufen wird), macht aber definitiv Sinn.
Luke Davis
Es ist nicht sehr ungewöhnlich: Eine einheitliche Funktionsaufrufsyntax wurde bereits in einigen Sprachen vorgeschlagen / implementiert.
AndiDog
25

In Python ist eine Methode eine Funktion, die aufgrund des Objekttyps für ein bestimmtes Objekt verfügbar ist .

Wenn Sie beispielsweise erstellen my_list = [1, 2, 3], kann die appendMethode angewendet werden, my_listda es sich um eine Python-Liste handelt : my_list.append(4). Alle Listen haben eine appendMethode, einfach weil sie Listen sind.

Wenn Sie ein anderes Beispiel erstellen my_string = 'some lowercase text', kann die upperMethode einfach angewendet werden, my_stringweil es sich um eine Python-Zeichenfolge handelt : my_string.upper().

Listen haben keine upperMethode und Strings haben keine appendMethode. Warum? Da Methoden nur für ein bestimmtes Objekt existieren, wenn sie explizit für diesen Objekttyp definiert wurden , und die Entwickler von Python (bisher) entschieden haben, dass diese bestimmten Methoden für diese bestimmten Objekte nicht benötigt werden.

Um eine Methode aufzurufen, lautet das Format object_name.method_name(), und alle Argumente für die Methode werden in Klammern aufgeführt. Die Methode wirkt implizit auf das zu benennende Objekt, und daher haben einige Methoden keine angegebenen Argumente, da das Objekt selbst das einzige notwendige Argument ist. Beispielsweise my_string.upper()sind keine Argumente aufgelistet, da das einzige erforderliche Argument das Objekt selbst ist my_string.

Ein häufiger Punkt der Verwirrung betrifft Folgendes:

import math
math.sqrt(81)

Ist sqrteine Methode des mathObjekts? Nein. So rufen Sie die sqrtFunktion vom mathModul aus auf. Das verwendete Format ist module_name.function_name()anstelle von object_name.method_name(). Im Allgemeinen ist die einzige Art und Weise zwischen den beiden Formaten (visuell) zu unterscheiden , in dem Rest des Codes schauen und sehen , ob das Teil vor der Periode ( math, my_list, my_string) als ein Objekt oder ein Modul definiert ist.

Kevin Markham
quelle
4

Entschuldigung, aber meiner Meinung nach hat RichieHindle völlig Recht, diese Methode zu sagen ...

Es ist eine Funktion, die Mitglied einer Klasse ist.

Hier ist das Beispiel einer Funktion, die Mitglied der Klasse wird. Seitdem verhält es sich wie eine Methode der Klasse. Beginnen wir mit der leeren Klasse und der normalen Funktion mit einem Argument:

>>> class C:
...     pass
...
>>> def func(self):
...     print 'func called'
...
>>> func('whatever')
func called

Jetzt fügen wir der CKlasse ein Mitglied hinzu , das den Verweis auf die Funktion darstellt. Danach können wir die Instanz der Klasse erstellen und ihre Methode aufrufen, als ob sie innerhalb der Klasse definiert worden wäre:

>>> C.func = func
>>> o = C()
>>> o.func()
func called

Wir können auch die alternative Methode zum Aufrufen der Methode verwenden:

>>> C.func(o)
func called

Das o.funcgerade manifestiert sich genauso wie die Klassenmethode:

>>> o.func
<bound method C.func of <__main__.C instance at 0x000000000229ACC8>>

Und wir können den umgekehrten Ansatz ausprobieren. Definieren wir eine Klasse und stehlen ihre Methode als Funktion:

>>> class A:
...     def func(self):
...         print 'aaa'
...
>>> a = A()
>>> a.func
<bound method A.func of <__main__.A instance at 0x000000000229AD08>>
>>> a.func()
aaa

Bisher sieht es genauso aus. Nun stiehlt die Funktion:

>>> afunc = A.func
>>> afunc(a)
aaa    

Die Wahrheit ist, dass die Methode kein "was auch immer" -Argument akzeptiert:

>>> afunc('whatever')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method func() must be called with A instance as first 
  argument (got str instance instead)

IMHO, dies ist nicht das Argument gegen Methode ist eine Funktion, die Mitglied einer Klasse ist .

Später fand die Antwort von Alex Martelli, die im Grunde das gleiche sagt. Entschuldigung, wenn Sie es als Vervielfältigung betrachten :)

pepr
quelle
Bei delnan: Sie haben geschrieben: "Die Instanz muss nicht explizit / manuell übergeben werden, wenn eine Methode darauf aufgerufen wird." Eigentlich müssen Sie es explizit übergeben. Der einzige syntaktische Unterschied besteht darin, dass Sie es nicht als erstes Argument in Klammern schreiben. Das Setzen vor den Methodennamen (durch Punkte getrennt) und das Weglassen der Klassenkennung ist eigentlich ein synaktischer Zucker.
Pepr
0

http://docs.python.org/2/tutorial/classes.html#method-objects

Normalerweise wird eine Methode direkt nach dem Binden aufgerufen:

x.f()

Im MyClass-Beispiel wird die Zeichenfolge 'Hallo Welt' zurückgegeben. Es ist jedoch nicht erforderlich, eine Methode sofort aufzurufen: xf ist ein Methodenobjekt und kann gespeichert und zu einem späteren Zeitpunkt aufgerufen werden. Zum Beispiel:

xf = x.f
while True:
    print xf()

wird weiterhin Hallo Welt bis zum Ende der Zeit drucken.

Was genau passiert, wenn eine Methode aufgerufen wird? Möglicherweise haben Sie bemerkt, dass xf () ohne das obige Argument aufgerufen wurde, obwohl die Funktionsdefinition für f () ein Argument angegeben hat. Was ist mit dem Streit passiert? Sicherlich löst Python eine Ausnahme aus, wenn eine Funktion, für die ein Argument erforderlich ist, ohne eine aufgerufen wird - auch wenn das Argument nicht tatsächlich verwendet wird ...

Vielleicht haben Sie die Antwort erraten: Das Besondere an Methoden ist, dass das Objekt als erstes Argument der Funktion übergeben wird. In unserem Beispiel entspricht der Aufruf xf () genau MyClass.f (x). Im Allgemeinen entspricht das Aufrufen einer Methode mit einer Liste von n Argumenten dem Aufrufen der entsprechenden Funktion mit einer Argumentliste, die durch Einfügen des Objekts der Methode vor dem ersten Argument erstellt wird.

Wenn Sie immer noch nicht verstehen, wie Methoden funktionieren, kann ein Blick auf die Implementierung möglicherweise die Dinge klären. Wenn auf ein Instanzattribut verwiesen wird, das kein Datenattribut ist, wird seine Klasse durchsucht. Wenn der Name ein gültiges Klassenattribut angibt, das ein Funktionsobjekt ist, wird ein Methodenobjekt erstellt, indem das Instanzobjekt und das gerade gefundene Funktionsobjekt in einem abstrakten Objekt gepackt werden (Zeiger darauf): Dies ist das Methodenobjekt. Wenn das Methodenobjekt mit einer Argumentliste aufgerufen wird, wird aus dem Instanzobjekt und der Argumentliste eine neue Argumentliste erstellt, und das Funktionsobjekt wird mit dieser neuen Argumentliste aufgerufen.

acmerfight
quelle
0

Wenn Sie sich ein Objekt als einem Substantiv ähnlich vorstellen, ähnelt eine Methode einem Verb. Verwenden Sie eine Methode direkt nach einem Objekt (dh eine Zeichenfolge oder eine Liste), um die Aktion einer Methode darauf anzuwenden.

Malik Singleton
quelle
0

Um Methoden zu verstehen, müssen Sie zunächst objektorientiert programmieren: Nehmen wir ein Auto als Klasse. Alle Autos haben Gemeinsamkeiten und Dinge, die sie einzigartig machen, zum Beispiel haben alle Autos 4 Räder, Türen, ein Lenkrad ... aber Ihr individuelles Auto (nennen wir es my_toyota) ist rot und geht von 0 bis 60 Zoll 5.6s Weiter befindet sich das Auto derzeit in meinem Haus, die Türen sind verschlossen, der Kofferraum ist leer ... All dies sind Eigenschaften der Instanz von my_toyota. your_honda ist vielleicht unterwegs, Kofferraum voller Lebensmittel ...

Es gibt jedoch Dinge, die Sie mit dem Auto tun können. Sie können es fahren, Sie können die Tür öffnen, Sie können es laden. Diese Dinge, die Sie mit einem Auto tun können, sind Methoden des Autos und ändern die Eigenschaften der spezifischen Instanz.

als Pseudocode würden Sie tun:

my_toyota.drive(shop)

um den Standort von meinem Zuhause in den Laden zu ändern oder

my_toyota.load([milk, butter, bread]

Dadurch wird der Kofferraum nun mit [Milch, Butter, Brot] beladen.

Als solche Methode ist praktisch eine Funktion, die als Teil des Objekts fungiert:

class Car(vehicle)
    n_wheels = 4

    load(self, stuff):
    '''this is a method, to load stuff into the trunk of the car'''
        self.open_trunk
        self.trunk.append(stuff)
        self.close_trunk

Der Code wäre dann:

my_toyota = Car(red)
my_shopping = [milk, butter, bread]
my_toyota.load(my_shopping)
Christian Kunert
quelle