Heim > Artikel > Backend-Entwicklung > Über die Verwendung von with in Python
Der Inhalt dieses Artikels befasst sich mit der Verwendung von with in Python.
Es gibt einige Aufgaben, die möglicherweise im Voraus eingerichtet und anschließend aufgeräumt werden müssen. Für dieses Szenario bietet die with-Anweisung von Python eine sehr praktische Möglichkeit, damit umzugehen. Ein gutes Beispiel ist die Dateiverwaltung, bei der Sie ein Dateihandle abrufen, Daten aus der Datei lesen und dann das Dateihandle schließen müssen.
Wenn Sie die with-Anweisung nicht verwenden, lautet der Code wie folgt:
file = open("/tmp/foo.txt") data = file.read()file.close()
Hier gibt es zwei Probleme:
Eines ist, dass Sie möglicherweise vergessen, zu schließen das Dateihandle;
Das andere ist das Lesen der Datei. Beim Abrufen von Daten ist eine Ausnahme aufgetreten und es wurde keine Verarbeitung durchgeführt.
Hier ist eine erweiterte Version, die Ausnahmen behandelt:
try: f = open('xxx')except: print 'fail to open' exit(-1)try: do somethingexcept: do somethingfinally: f.close()
Dieser Code funktioniert zwar gut, ist aber zu ausführlich.
Dies ist die Zeit, in der er sein Können unter Beweis stellen kann. Neben einer eleganteren Syntax kann es auch vom Kontext generierte Ausnahmen sehr gut verarbeiten.
Das Folgende ist der Code für die with-Version:
with open("/tmp/foo.txt") as file: data = file.read()
Nachdem die Anweisung unmittelbar nach with ausgewertet wurde, wird der __enter__ von Das Objekt wird als Methode zurückgegeben () und der Rückgabewert dieser Methode wird der Variablen nach as zugewiesen.
Wenn alle folgenden Codeblöcke ausgeführt werden, wird die Methode __exit__() des zuvor zurückgegebenen Objekts aufgerufen.
Das folgende Beispiel kann konkret veranschaulichen, wie with funktioniert:
#!/usr/bin/env python# with_example01.pyclass Sample: def __enter__(self): print "In __enter__()" return "Foo" def __exit__(self, type, value, trace): print "In __exit__()"def get_sample(): return Sample()with get_sample() as sample: print "sample:", sample
Führen Sie den Code aus, die Ausgabe ist wie folgt
bash-3.2$ ./with_example01.pyIn __enter__()sample: FooIn __exit__()
正如你看到的: 1. __enter__()方法被执行 2. __enter__()方法返回的值 - 这个例子中是”Foo”,赋值给变量’sample’ 3. 执行代码块,打印变量”sample”的值为 “Foo” 4. __exit__()方法被调用
with真正强大之处是它可以处理异常。可能你已经注意到Sample类的 __exit__ 方法有三个参数 val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。
#!/usr/bin/env python# with_example02.pyclass Sample: def __enter__(self): return self def __exit__(self, type, value, trace): print "type:", type print "value:", value print "trace:", trace def do_something(self): bar = 1/0 return bar + 10with Sample() as sample: sample.do_something()
这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有 __enter__() 和 __exit__() 方法即可。此例中,Sample()的 __enter__() 方法返回新创建的Sample对象,并赋值给变量sample。
代码执行后:
bash-3.2$ ./with_example02.py type: <type 'exceptions.ZeropisionError'>value: integer pision or modulo by zerotrace: <traceback object at 0x1004a8128> Traceback (most recent call last): File "./with_example02.py", line 19, in <module> sample.do_something() File "./with_example02.py", line 15, in do_something bar = 1/0ZeropisionError: integer pision or modulo by zero
实际上,在with后面的代码块抛出任何异常时,__exit__() 方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给 __exit__() 方法,因此抛出的ZeropisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在 __exit__ 方法当中。
另外,__exit__ 除了用于tear things down,还可以进行异常的监控和处理,注意后几个参数。要跳过一个异常,只需要返回该函数True即可。
下面的样例代码跳过了所有的TypeError,而让其他异常正常抛出。
def __exit__(self, type, value, traceback): return isinstance(value, TypeError)
上文说了 __exit__ 函数可以进行部分异常的处理,如果我们不在这个函数中处理异常,他会正常抛出,这时候我们可以这样写(python 2.7及以上版本,之前的版本参考使用contextlib.nested这个库函数):
try: with open( "a.txt" ) as f : do something except xxxError: do something about exception
总之,with-as表达式极大的简化了每次写finally的工作,这对保持代码的优雅性是有极大帮助的。
如果有多个项,我们可以这么写:
with open("x.txt") as f1, open('xxx.txt') as f2: do something with f1,f2
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
Um die with-Anweisung verwenden zu können, müssen Sie zunächst das Konzept des Kontextmanagers verstehen. Mit einem Kontextmanager kann die with-Anweisung funktionieren.
Im Folgenden finden Sie eine Reihe von Konzepten im Zusammenhang mit Kontextmanagern und Anweisungen.
Kontextverwaltungsprotokoll: Enthält die Methoden __enter__() und __exit__(). Objekte, die dieses Protokoll unterstützen, müssen diese beiden Methoden implementieren.
Kontextmanager: Ein Objekt, das das Kontextverwaltungsprotokoll unterstützt. Dieses Objekt implementiert die Methoden __enter__() und __exit__(). Der Kontextmanager definiert den Laufzeitkontext, der beim Ausführen der with-Anweisung eingerichtet werden soll, und ist für die Ausführung der Ein- und Ausstiegsvorgänge im Kontext des with-Anweisungsblocks verantwortlich. Ein Kontextmanager wird normalerweise mit der with-Anweisung aufgerufen, kann aber auch durch den direkten Aufruf seiner Methoden verwendet werden.
Laufzeitkontext: Vom Kontextmanager erstellt und über die Methoden __enter__() und __exit__() implementiert. Die Methode __enter__() tritt in den Laufzeitkontext ein, bevor der Anweisungstext ausgeführt wird Laufzeitkontext, nachdem der Anweisungstext ausgeführt wurde. Die with-Anweisung unterstützt das Konzept des Laufzeitkontexts.
Kontextausdruck: Der Ausdruck, der dem Schlüsselwort with in der with-Anweisung folgt und ein Kontextmanagerobjekt zurückgibt.
Anweisungskörper (with-body): Der in die with-Anweisung eingeschlossene Codeblock ruft die __enter__()-Methode des Kontextmanagers auf, bevor der Anweisungskörper ausgeführt wird, und die __exit__()-Methode wird ausgeführt, nachdem der Anweisungskörper ausgeführt wurde hingerichtet.
Verwandte Links:
1.http://blog.kissdata.com/2014/05/23/python-with.html
2.https://www.ibm .com/developerworks/cn/opensource/os-cn-pythonwith/
Verwandte Empfehlungen:
So verstehen Sie die with-Anweisung in Python
Detaillierte Erläuterung der Verwendung von „Focus-within“
Das obige ist der detaillierte Inhalt vonÜber die Verwendung von with in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!