Heim Backend-Entwicklung Python-Tutorial Ausführliche Erklärung der Syntax von yield from in Python 3

Ausführliche Erklärung der Syntax von yield from in Python 3

Feb 21, 2017 am 10:11 AM

In Python 3.3 hat der Generator eine neue Syntax yield from. Welche Funktion hat yield from? Wie ist die Syntax? Der folgende Artikel stellt Ihnen hauptsächlich die relevanten Informationen zur Syntaxausbeute in Python 3 vor. Freunde, die sie benötigen, können darauf zurückgreifen.

Vorwort

Ich habe kürzlich an Autobahn herumgebastelt und es gab ein auf Asyncio basierendes Beispiel. Ich dachte darüber nach, es auf pypy3 zu installieren und auszuführen, aber es.. . fehlgeschlagen. . pip install asyncio Ungültige Syntax direkt melden. Auf den ersten Blick dachte ich, es gäbe ein Problem mit der 2to3-Verarbeitung – man kann es mir nicht verübeln, naja ~ viele Pakete werden in 2 geschrieben und dann in 3 konvertiert – es stellte sich heraus, dass Asyncio nur unterstützt In der Version 3.3+ habe ich mir den Code noch einmal angeschaut und plötzlich einen Satz gefunden: yield from Ich weiß, aber yield ist ein magisches Pferd? yield from

PEP-380

Nun, ich bin über Google auf diesen Titel gekommen.

s früheres und gegenwärtiges Leben sind alle in diesem PEP enthalten. Die allgemeine Idee ist die ursprüngliche.yield fromDie Anweisung kann die CPU-Steuerung nur an den direkten Aufrufer zurückgeben. Wenn Sie die Logik mit einer yield-Anweisung in einem Generator oder einer Coroutine in einen anderen Generator (ursprünglicher Subgenerator) rekonstruieren möchten, ist dies sehr schwierig problematisch, da der Generator außerhalb für die Nachrichtenweitergabe verantwortlich ist, sodass jemand die Idee hatte, Python die Nachrichtenweitergabe kapseln zu lassen, um sie für Programmierer transparent zu machen, also gab es yield. yield from

PEP-380 gibt die Semantik von

oder das Verhaltensmuster an, das verschachtelte Generatoren haben sollten. yield from

Angenommen, es gibt eine solche Anweisung in Funktion A

yield from B()
Nach dem Login kopieren

gibt ein iterierbares (iterierbares) Objekt b zurück, dann A () gibt einen Generator zurück – gemäß unserer Namenskonvention ist der Name a – dann: B()

  1. Jeder durch die B-Iteration generierte Wert wird direkt an den Aufruf von a who übergeben.

  2. Alle über die Sendemethode an a gesendeten Werte werden direkt an b übergeben. Wenn der gesendete Wert None ist, wird die

    -Methode von b aufgerufen, andernfalls die Sendemethode von b heißt . Wenn der Methodenaufruf an b eine StopIteration-Ausnahme generiert, führt a weiterhin die Anweisungen nach __next__() aus, und andere Ausnahmen werden an a weitergegeben, was dazu führt, dass a beim Ausführen von yield from eine Ausnahme auslöst. yield from

  3. Wenn eine andere Ausnahme als GeneratorExit in a geworfen wird, wird die Ausnahme direkt in b geworfen. Wenn die throw-Methode von b StopIteration auslöst, wird a weiterhin ausgeführt. Andere Ausnahmen führen dazu, dass a ebenfalls eine Ausnahme auslöst.

  4. Wenn eine GeneratorExit-Ausnahme in a ausgelöst wird oder die Close-Methode von a aufgerufen wird und b auch eine Close-Methode hat, wird auch die Close-Methode von b aufgerufen. Wenn diese Methode von b eine Ausnahme auslöst, führt sie dazu, dass auch a eine Ausnahme auslöst. Im Gegenteil, wenn b erfolgreich geschlossen wird, löst a ebenfalls eine Ausnahme aus, es handelt sich jedoch um eine bestimmte GeneratorExit-Ausnahme.

  5. Das Auswertungsergebnis des

    -Ausdrucks in a ist der erste Parameter der StopIteration-Ausnahme, die am Ende der Iteration von b ausgelöst wird. yield from

  6. Die

    -Anweisung in b löst tatsächlich eine return <expr>-Ausnahme aus, sodass der Rückgabewert in b zum Rückgabewert des StopIteration(<expr>) -Ausdrucks in a wird. yield from

Warum hat Shenma so viele Anforderungen? Da das Verhalten von Generatoren nach dem Hinzufügen der Throw-Methode sehr kompliziert wird, insbesondere wenn mehrere Generatoren zusammengeschaltet sind, sind für deren Betrieb Primitive erforderlich, die der Prozessverwaltung ähneln. Alle oben genannten Anforderungen dienen der Vereinheitlichung des inhärent komplexen Verhaltens des Generators und können daher natürlich nicht vereinfacht werden.

Ich gebe zu, dass ich nicht verstanden habe, was der Autor des PEP sagen wollte, daher könnte es hilfreich sein, es „umzugestalten“.

Ein nutzloses Beispiel

Es ist nutzlos, weil Sie das Programm wahrscheinlich nicht wirklich so schreiben wollen, aber... Wie auch immer, es reicht aus, um das Problem zu veranschaulichen . .

Stellen Sie sich eine Generatorfunktion wie diese vor:

def inner():
 coef = 1
 total = 0
 while True:
 try:
  input_val = yield total
  total = total + coef * input_val
 except SwitchSign:
  coef = -(coef)
 except BreakOut:
  return total
Nach dem Login kopieren

Der von dieser Funktion generierte Generator akkumuliert den von der Sendemethode empfangenen Wert die lokale Variable total und stoppt die Iteration, wenn eine BreakOut-Ausnahme empfangen wird; was die andere SwitchSign-Ausnahme betrifft, sollte sie nicht schwer zu verstehen sein, daher werde ich sie hier nicht verraten.

Aus Code-Sicht empfängt der durch die Funktion

erhaltene Generator Daten zur Berechnung durch Senden und übernimmt gleichzeitig die Steuerung von externem Code über die Throw-Methode, um verschiedene Codezweige auszuführen ist bisher sehr klar. inner()

Als nächstes müssen wir aufgrund geänderter Anforderungen Initialisierungs- und Site-Bereinigungscode vor und nach dem

-Code hinzufügen. Da ich der Meinung bin: „Fass keinen Code an, der nicht kaputt ist“, habe ich beschlossen, inner() so zu belassen, wie es ist, und dann ein weiteres inner() zu schreiben, den hinzugefügten Code in outer() einzufügen und die gleichen Operationen wie <🎜 bereitzustellen > Schnittstelle. Da outer() mehrere Funktionen des Generators nutzt, muss inner() auch diese fünf Dinge tun: inner()

  1. outer()必须生成一个generator;

  2. 在每一步的迭代中,outer()要帮助inner()返回迭代值;

  3. 在每一步的迭代中,outer()要帮助inner()接收外部发送的数据;

  4. 在每一步的迭代中,outer()要处理inner()接收和抛出所有异常;

  5. outer()被close的时候,inner()也要被正确地close掉。

根据上面的要求,在只有yield的世界里,outer()可能是长这样的:

def outer1():
 print("Before inner(), I do this.")
 i_gen = inner()
 input_val = None
 ret_val = i_gen.send(input_val)
 while True:
 try:
  input_val = yield ret_val
  ret_val = i_gen.send(input_val)
 except StopIteration:
  break
 except Exception as err:
  try:
  ret_val = i_gen.throw(err)
  except StopIteration:
  break
 print("After inner(), I do that.")
Nach dem Login kopieren

WTF,这段代码比inner()本身还要长,而且还没处理close操作。

现在我们来试试外星科技:

def outer2():
 print("Before inner(), I do this.")
 yield from inner()
 print("After inner(), I do that.")
Nach dem Login kopieren

除了完全符合上面的要求外,这四行代码打印出来的时候还能省点纸。

我们可以在outer1()outer2()上分别测试 数据 以及 异常 的传递,不难发现这两个generator的行为基本上是一致的。既然如此, 外星科技当然在大多数情况下是首选。

对generator和coroutine的疑问

从以前接触到Python下的coroutine就觉得它怪怪的,我能看清它们的 行为模式,但是并不明白为什么要使用这种模式,generator和 coroutine具有一样的对外接口,是generator造就了coroutine呢,还 是coroutine造就了generator?最让我百思不得其解的是,Python下 的coroutine将“消息传递”和“调度”这两种操作绑在一个yield 上——即便有了yield from,这个状况还是没变过——我看不出这样做 的必要性。如果一开始就从语法层面将这两种语义分开,并且为 generator和coroutine分别设计一套接口,coroutine的概念大概也会 容易理解一些。

更多Python 3中的yield from语法详解相关文章请关注PHP中文网!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie löste ich das Problem der Berechtigungen beim Betrachten der Python -Version in Linux Terminal? Wie löste ich das Problem der Berechtigungen beim Betrachten der Python -Version in Linux Terminal? Apr 01, 2025 pm 05:09 PM

Lösung für Erlaubnisprobleme beim Betrachten der Python -Version in Linux Terminal Wenn Sie versuchen, die Python -Version in Linux Terminal anzuzeigen, geben Sie Python ein ...

Wie lehre ich innerhalb von 10 Stunden die Grundlagen für Computer-Anfänger-Programmierbasis in Projekt- und problemorientierten Methoden? Wie lehre ich innerhalb von 10 Stunden die Grundlagen für Computer-Anfänger-Programmierbasis in Projekt- und problemorientierten Methoden? Apr 02, 2025 am 07:18 AM

Wie lehre ich innerhalb von 10 Stunden die Grundlagen für Computer -Anfänger für Programmierungen? Wenn Sie nur 10 Stunden Zeit haben, um Computer -Anfänger zu unterrichten, was Sie mit Programmierkenntnissen unterrichten möchten, was würden Sie dann beibringen ...

Wie kann man vom Browser vermeiden, wenn man überall Fiddler für das Lesen des Menschen in der Mitte verwendet? Wie kann man vom Browser vermeiden, wenn man überall Fiddler für das Lesen des Menschen in der Mitte verwendet? Apr 02, 2025 am 07:15 AM

Wie kann man nicht erkannt werden, wenn Sie Fiddlereverywhere für Man-in-the-Middle-Lesungen verwenden, wenn Sie FiddLereverywhere verwenden ...

Wie kann ich die gesamte Spalte eines Datenrahmens effizient in einen anderen Datenrahmen mit verschiedenen Strukturen in Python kopieren? Wie kann ich die gesamte Spalte eines Datenrahmens effizient in einen anderen Datenrahmen mit verschiedenen Strukturen in Python kopieren? Apr 01, 2025 pm 11:15 PM

Bei der Verwendung von Pythons Pandas -Bibliothek ist das Kopieren von ganzen Spalten zwischen zwei Datenrahmen mit unterschiedlichen Strukturen ein häufiges Problem. Angenommen, wir haben zwei Daten ...

Wie hört Uvicorn kontinuierlich auf HTTP -Anfragen ohne Serving_forver () an? Wie hört Uvicorn kontinuierlich auf HTTP -Anfragen ohne Serving_forver () an? Apr 01, 2025 pm 10:51 PM

Wie hört Uvicorn kontinuierlich auf HTTP -Anfragen an? Uvicorn ist ein leichter Webserver, der auf ASGI basiert. Eine seiner Kernfunktionen ist es, auf HTTP -Anfragen zu hören und weiterzumachen ...

Wie bekomme ich Nachrichtendaten, die den Anti-Crawler-Mechanismus von Investing.com umgehen? Wie bekomme ich Nachrichtendaten, die den Anti-Crawler-Mechanismus von Investing.com umgehen? Apr 02, 2025 am 07:03 AM

Verständnis der Anti-Crawling-Strategie von Investing.com Viele Menschen versuchen oft, Nachrichten von Investing.com (https://cn.investing.com/news/latest-news) zu kriechen ...

Wie erstelle ich dynamisch ein Objekt über eine Zeichenfolge und rufe seine Methoden in Python auf? Wie erstelle ich dynamisch ein Objekt über eine Zeichenfolge und rufe seine Methoden in Python auf? Apr 01, 2025 pm 11:18 PM

Wie erstellt in Python ein Objekt dynamisch über eine Zeichenfolge und ruft seine Methoden auf? Dies ist eine häufige Programmieranforderung, insbesondere wenn sie konfiguriert oder ausgeführt werden muss ...

See all articles