Python Language
Het pass statement
Zoeken…
Syntaxis
- voorbij gaan aan
Opmerkingen
Waarom zou je de tolk ooit willen vertellen expliciet niets te doen? Python heeft de syntactische vereiste dat codeblokken (na if
, except
, def
, class
enz.) Niet leeg mogen zijn.
Maar soms is een leeg codeblok op zichzelf nuttig. Een leeg class
kan een nieuwe, andere klasse definiëren, zoals een uitzondering die kan worden gevangen. Een leeg except
blok kan de eenvoudigste manier zijn om “om vergeving vragen later” uit te drukken als er niets is om vergeving te vragen. Als een iterator doet al het zware werk, een lege for
lus om alleen nog maar de iterator kan nuttig zijn.
Daarom, als er niets wordt verondersteld te gebeuren in een codeblok, is een pass
nodig voor een dergelijk blok om geen IndentationError
produceren. Als alternatief kan elke bewering (inclusief alleen een te evalueren term, zoals de letterlijke Ellipsis
...
of een string, meestal een docstring) worden gebruikt, maar de pass
maakt duidelijk dat er inderdaad niets wordt verondersteld te gebeuren, en dat dit niet nodig is om daadwerkelijk te worden geëvalueerd en (althans tijdelijk) in het geheugen te worden opgeslagen. Hier is een kleine geannoteerde verzameling van de meest voorkomende pass
die mijn weg kruisten - samen met enkele opmerkingen over goed en slecht gebruik.
Een bepaald type
Exception
(bijvoorbeeld uitxml
) negeren:try: self.version = "Expat %d.%d.%d" % expat.version_info except AttributeError: pass # unknown
Opmerking: het negeren van alle soorten verhogingen, zoals in het volgende voorbeeld van
pandas
, wordt over het algemeen als een slechte gewoonte beschouwd, omdat het ook uitzonderingen vangt die waarschijnlijk aan de beller moeten worden doorgegeven, bijvoorbeeldKeyboardInterrupt
ofSystemExit
(of zelfsHardwareIsOnFireError
- Hoe weet u dat? u werkt niet op een aangepast vak met specifieke gedefinieerde fouten, waarover een oproepende toepassing zou willen weten?).try: os.unlink(filename_larry) except: pass
Gebruik in plaats daarvan ten minste
except Error:
of in dit geval bij voorkeurexcept OSError:
wordt als een veel betere praktijk beschouwd. Een snelle analyse van alle python-modules die ik heb geïnstalleerd, gaf me dat meer dan 10% van alleexcept ...: pass
statements alle uitzonderingen bevatten, dus het is nog steeds een frequent patroon in python-programmering.Een uitzonderingsklasse afleiden die geen nieuw gedrag toevoegt (bijvoorbeeld in
scipy
):class CompileError(Exception): pass
Evenzo hebben klassen die bedoeld zijn als abstracte basisklasse vaak een expliciete lege
__init__
of andere methoden die subklassen zouden moeten afleiden. (bijvoorbeeldpebl
)class _BaseSubmittingController(_BaseController): def submit(self, tasks): pass def retrieve(self, deferred_results): pass
Het testen van die code werkt goed voor een paar testwaarden, zonder de resultaten te
mpmath
(vanmpmath
):for x, error in MDNewton(mp, f, (1,-2), verbose=0, norm=lambda x: norm(x, inf)): pass
In klasse- of functiedefinities is er vaak al een docstring aanwezig als de verplichte instructie die als het enige in het blok moet worden uitgevoerd. In dergelijke gevallen kan het blok naast de docstring
pass
bevatten om te zeggen: "Dit is inderdaad bedoeld om niets te doen.", Bijvoorbeeld inpebl
:class ParsingError(Exception): """Error encountered while parsing an ill-formed datafile.""" pass
In sommige gevallen wordt
pass
gebruikt als een tijdelijke aanduiding om te zeggen: "Deze methode / klasse / if-block / ... is nog niet geïmplementeerd, maar dit is de plek om het te doen", hoewel ik persoonlijk de voorkeur geef aan de letterlijkeEllipsis
...
(OPMERKING: alleen python-3) om een strikt onderscheid te maken tussen dit en de opzettelijke "no-op" in het vorige voorbeeld. Als ik bijvoorbeeld een model in grote lijnen schrijf, zou ik kunnen schrijvendef update_agent(agent): ...
waar anderen misschien hebben
def update_agent(agent): pass
voordat
def time_step(agents): for agent in agents: update_agent(agent)
als een herinnering om de functie
update_agent
op een later tijdstip in te vullen, maar voer al enkele tests uit om te zien of de rest van de code zich gedraagt zoals bedoeld. (Een derde optie voor dit geval israise NotImplementedError
. Dit is met name nuttig voor twee gevallen: ofwel: “Deze abstracte methode moet door elke subklasse worden geïmplementeerd, er is geen generieke manier om het in deze basisklasse te definiëren” , of “Deze functie , met deze naam, is nog niet geïmplementeerd in deze release, maar zo ziet zijn handtekening eruit ” )
Negeer een uitzondering
try:
metadata = metadata['properties']
except KeyError:
pass
Maak een nieuwe uitzondering die kan worden gevangen
class CompileError(Exception):
pass