426 Stimmen

Wie wird die Anweisung "pass" verwendet?

Ich bin gerade dabei, Python zu lernen, und bin bei dem Abschnitt über die pass Erklärung. Der Leitfaden, den ich verwende, definiert es als eine Null-Anweisung, die üblicherweise als Platzhalter verwendet wird.

Ich verstehe allerdings immer noch nicht ganz, was das bedeutet. Was wäre eine einfache/grundlegende Situation, in der die pass Aussage verwendet werden würde und warum sie benötigt würde?

504voto

sebastian_oe Punkte 7156

Angenommen, Sie entwerfen eine neue Klasse mit einigen Methoden, die Sie noch nicht implementieren wollen.

class MyClass(object):
    def meth_a(self):
        pass

    def meth_b(self):
        print "I'm meth_b"

Wenn Sie die pass würde der Code nicht ausgeführt werden.

Sie erhalten dann eine:

IndentationError: expected an indented block

Zusammenfassend lässt sich sagen, dass die pass Anweisung tut nichts Besonderes, aber sie kann als Platzhalter dienen, wie hier gezeigt.

254voto

Anaphory Punkte 5590

Python hat die syntaktische Anforderung, dass Codeblöcke (nach if , except , def , class usw.) können nicht leer sein. Leere Codeblöcke sind jedoch in einer Vielzahl von Kontexten nützlich, wie z. B. in den folgenden Beispielen, die die häufigsten Anwendungsfälle sind, die ich gesehen habe.

Wenn also in einem Codeblock nichts passieren soll, muss ein pass ist erforderlich, damit ein solcher Block nicht zu einem IndentationError . Alternativ kann jede beliebige Anweisung (auch nur ein auszuwertender Term, wie der Ellipsis wörtlich ... oder eine Zeichenkette, meist ein Docstring) verwendet werden, aber die pass macht deutlich, dass in der Tat nichts passieren soll und nicht tatsächlich ausgewertet und (zumindest vorübergehend) im Speicher abgelegt werden muss.

  • Ignorieren (aller oder) einer bestimmten Art von Exception (Beispiel aus xml ):

     try:
         self.version = "Expat %d.%d.%d" % expat.version_info
     except AttributeError:
         pass # unknown

    Anmerkung: Ignorieren aller Arten von Erhöhungen, wie im folgenden Beispiel aus pandas wird im Allgemeinen als schlechte Praxis angesehen, da es auch Ausnahmen abfängt, die wahrscheinlich an den Aufrufer weitergegeben werden sollten, z. B. KeyboardInterrupt ou SystemExit (oder sogar HardwareIsOnFireError - Woher wissen Sie, dass Sie nicht auf einer benutzerdefinierten Box mit spezifischen Fehlern laufen, über die eine aufrufende Anwendung Bescheid wissen möchte?).

     try:
         os.unlink(filename_larry)
     except:
         pass

    Stattdessen sollten mindestens except Error: oder in diesem Fall vorzugsweise except OSError: wird als wesentlich bessere Praxis angesehen. Eine schnelle Analyse aller Python-Module, die ich installiert habe, ergab, dass mehr als 10% aller except ...: pass Anweisungen fangen alle Ausnahmen ab, daher ist es immer noch ein häufiges Muster in der Python-Programmierung.

  • Die Ableitung einer Ausnahmeklasse, die kein neues Verhalten hinzufügt (z. B. in SciPy ):

     class CompileError(Exception):
         pass

    Ähnlich haben Klassen, die als abstrakte Basisklasse gedacht sind, oft eine explizite leere __init__ oder andere Methoden, die von Unterklassen abgeleitet werden sollen (z.B., pebl ):

     class _BaseSubmittingController(_BaseController):
         def submit(self, tasks): pass
         def retrieve(self, deferred_results): pass
  • Testen, dass der Code für einige wenige Testwerte ordnungsgemäß ausgeführt wird, ohne sich um die Ergebnisse zu kümmern (von mpmath ):

     for x, error in MDNewton(mp, f, (1,-2), verbose=0,
                              norm=lambda x: norm(x, inf)):
         pass
  • In Klassen- oder Funktionsdefinitionen ist oft bereits ein Docstring vorhanden, da die obligatorische Erklärung als einziges Element des Blocks ausgeführt werden soll. In solchen Fällen kann der Block Folgendes enthalten pass darüber hinaus in den Docstring einfügen, um zu sagen: "Dies ist in der Tat dazu gedacht, nichts zu tun", zum Beispiel in pebl :

     class ParsingError(Exception):
         """Error encountered while parsing an ill-formed datafile."""
         pass
  • In einigen Fällen, pass wird als Platzhalter verwendet, um zu sagen: "Diese Methode/Klasse/if-Block/... wurde noch nicht implementiert, aber dies wird der Ort sein, an dem sie implementiert wird", obwohl ich persönlich die Ellipsis wörtlich ... um dies strikt von dem absichtlichen "no-op" im vorherigen Beispiel zu unterscheiden. ( Beachten Sie, dass das Ellipsis-Literal nur in Python 3 ein gültiger Ausdruck ist )

    Wenn ich zum Beispiel ein Modell in groben Zügen schreibe, könnte ich schreiben

     def update_agent(agent):
         ...

    wo andere vielleicht

     def update_agent(agent):
         pass

    vor

     def time_step(agents):
         for agent in agents:
             update_agent(agent)

    als Erinnerung zum Ausfüllen des update_agent Funktion zu einem späteren Zeitpunkt, aber führen Sie schon jetzt einige Tests durch, um zu sehen, ob sich der Rest des Codes wie vorgesehen verhält. (Eine dritte Möglichkeit für diesen Fall ist raise NotImplementedError . Dies ist vor allem in zwei Fällen nützlich: Entweder "Diese abstrakte Methode sollte von jeder Unterklasse implementiert werden, und es gibt keine generische Möglichkeit, sie in dieser Basisklasse zu definieren. o "Diese Funktion mit diesem Namen ist in dieser Version noch nicht implementiert, aber so wird ihre Signatur aussehen" )

25voto

Micah Walter Punkte 821

Abgesehen von seiner Verwendung als Platzhalter für nicht implementierte Funktionen, pass kann beim Ausfüllen einer if-else-Anweisung nützlich sein ("Explizit ist besser als implizit.")

def some_silly_transform(n):
    # Even numbers should be divided by 2
    if n % 2 == 0:
        n /= 2
        flag = True
    # Negative odd numbers should return their absolute value
    elif n < 0:
        n = -n
        flag = True
    # Otherwise, number should remain unchanged
    else:
        pass

Natürlich würde man in diesem Fall wahrscheinlich return anstelle einer Zuweisung, aber in Fällen, in denen eine Mutation erwünscht ist, funktioniert dies am besten.

Die Verwendung von pass ist hier besonders nützlich, um künftige Betreuer (einschließlich Ihnen selbst!) davor zu warnen, überflüssige Schritte außerhalb der bedingten Anweisungen zu setzen. Im obigen Beispiel, flag wird in den beiden genannten Fällen festgelegt, nicht aber in der else -Gehäuse. Ohne Verwendung pass könnte ein zukünftiger Programmierer die flag = True auf außerhalb der Bedingung - und damit auf flag en alle Fälle.


Ein weiterer Fall ist die Boilerplate-Funktion, die häufig am Ende einer Datei zu finden ist:

if __name__ == "__main__":
    pass

In einigen Dateien kann es sinnvoll sein, diese mit pass um die spätere Bearbeitung zu erleichtern und um deutlich zu machen, dass nichts erwartet wird, wenn die Datei allein ausgeführt wird.


Schließlich kann es, wie in anderen Antworten erwähnt, nützlich sein, nichts zu tun, wenn eine Ausnahme abgefangen wird:

try:
    n[i] = 0
except IndexError:
    pass

21voto

Schilcote Punkte 2314

Die beste und genaueste Art und Weise, sich vorzustellen pass ist eine Möglichkeit, dem Interpreter ausdrücklich zu sagen, dass er nichts tun soll. Auf dieselbe Weise wird der folgende Code:

def foo(x,y):
    return x+y

bedeutet: "Wenn ich die Funktion foo(x, y) aufrufe, addiere ich die beiden Zahlen, die die Bezeichnungen x und y darstellen, und gebe das Ergebnis zurück",

def bar():
    pass

bedeutet: "Wenn ich die Funktion bar() aufrufe, tue absolut nichts."

Die anderen Antworten sind richtig, aber es ist auch für einige Dinge nützlich, bei denen es nicht um das Halten von Plätzen geht.

In einem Code, an dem ich vor kurzem gearbeitet habe, mussten beispielsweise zwei Variablen geteilt werden, und es war möglich, dass der Divisor Null war.

c = a / b

erzeugt natürlich einen ZeroDivisionError, wenn b gleich Null ist. In dieser speziellen Situation war es das gewünschte Verhalten, c als Null zu belassen, wenn b Null war, also habe ich den folgenden Code verwendet:

try:
    c = a / b
except ZeroDivisionError:
    pass

Eine andere, weniger gebräuchliche Verwendung ist die eines praktischen Haltepunkts für den Debugger. Ich wollte zum Beispiel, dass ein Teil des Codes bei der 20. Iteration einer for... in-Anweisung im Debugger unterbrochen wird. Also:

for t in range(25):
    do_a_thing(t)
    if t == 20:
        pass

mit dem Haltepunkt bei Durchgang.

11voto

Ein üblicher Anwendungsfall, in dem es "so wie es ist" verwendet werden kann, ist die Überschreibung einer Klasse, um einen Typ zu erstellen (der ansonsten derselbe ist wie die Oberklasse), z. B.

class Error(Exception):
    pass

So können Sie aufziehen und fangen Error Ausnahmen. Hier kommt es auf die Art der Ausnahme an, nicht auf den Inhalt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X