# SOME DESCRIPTIVE TITLE. # Copyright (C) 2001 Python Software Foundation # This file is distributed under the same license as the Python package. # FIRST AUTHOR , YEAR. # # Translators: # 99 , 2026 # python-doc bot, 2026 # Freesand Leo , 2026 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Python 3.15\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2026-05-08 18:34+0000\n" "PO-Revision-Date: 2025-09-16 00:00+0000\n" "Last-Translator: Freesand Leo , 2026\n" "Language-Team: Chinese (China) (https://app.transifex.com/python-doc/teams/5390/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: ../../library/asyncio-dev.rst:7 msgid "Developing with asyncio" msgstr "用 asyncio 开发" #: ../../library/asyncio-dev.rst:9 msgid "" "Asynchronous programming is different from classic \"sequential\" " "programming." msgstr "异步编程与传统的“顺序”编程不同。" #: ../../library/asyncio-dev.rst:12 msgid "" "This page lists common mistakes and traps and explains how to avoid them." msgstr "本页列出常见的错误和陷阱,并解释如何避免它们。" #: ../../library/asyncio-dev.rst:19 msgid "Debug Mode" msgstr "调试模式" #: ../../library/asyncio-dev.rst:21 msgid "" "By default asyncio runs in production mode. In order to ease the " "development asyncio has a *debug mode*." msgstr "默认情况下,asyncio 以生产模式运行。为了简化开发,asyncio 还有一种*调试模式* 。" #: ../../library/asyncio-dev.rst:24 msgid "There are several ways to enable asyncio debug mode:" msgstr "有几种方法可以启用异步调试模式:" #: ../../library/asyncio-dev.rst:26 msgid "" "Setting the :envvar:`PYTHONASYNCIODEBUG` environment variable to ``1``." msgstr "将 :envvar:`PYTHONASYNCIODEBUG` 环境变量设置为 ``1``。" #: ../../library/asyncio-dev.rst:28 msgid "Using the :ref:`Python Development Mode `." msgstr "使用 :ref:`Python 开发模式 `。" #: ../../library/asyncio-dev.rst:30 msgid "Passing ``debug=True`` to :func:`asyncio.run`." msgstr "将 ``debug=True`` 传递给 :func:`asyncio.run`。" #: ../../library/asyncio-dev.rst:32 msgid "Calling :meth:`loop.set_debug`." msgstr "调用 :meth:`loop.set_debug`。" #: ../../library/asyncio-dev.rst:34 msgid "In addition to enabling the debug mode, consider also:" msgstr "除了启用调试模式外,还要考虑:" #: ../../library/asyncio-dev.rst:36 msgid "" "setting the log level of the :ref:`asyncio logger ` to " ":py:const:`logging.DEBUG`, for example the following snippet of code can be " "run at startup of the application::" msgstr "" "将 :ref:`asyncio logger ` 的级别设为 " ":py:const:`logging.DEBUG`,例如下面的代码片段可以在应用程序启动时运行::" #: ../../library/asyncio-dev.rst:40 msgid "logging.basicConfig(level=logging.DEBUG)" msgstr "logging.basicConfig(level=logging.DEBUG)" #: ../../library/asyncio-dev.rst:42 msgid "" "configuring the :mod:`warnings` module to display :exc:`ResourceWarning` " "warnings. One way of doing that is by using the :option:`-W` ``default`` " "command line option." msgstr "" "配置 :mod:`warnings` 模块以显示 :exc:`ResourceWarning` 警告。一种方法是使用 :option:`-W` " "``default`` 命令行选项。" #: ../../library/asyncio-dev.rst:47 msgid "When the debug mode is enabled:" msgstr "启用调试模式时:" #: ../../library/asyncio-dev.rst:49 msgid "" "Many non-threadsafe asyncio APIs (such as :meth:`loop.call_soon` and " ":meth:`loop.call_at` methods) raise an exception if they are called from a " "wrong thread." msgstr "" "许多非线程安全的异步 APIs (例如 :meth:`loop.call_soon` 和 :meth:`loop.call_at` " "方法),如果从错误的线程调用,则会引发异常。" #: ../../library/asyncio-dev.rst:53 msgid "" "The execution time of the I/O selector is logged if it takes too long to " "perform an I/O operation." msgstr "如果执行 I/O 操作花费的时间太长,则记录 I/O 选择器的执行时间。" #: ../../library/asyncio-dev.rst:56 msgid "" "Callbacks taking longer than 100 milliseconds are logged. The " ":attr:`loop.slow_callback_duration` attribute can be used to set the minimum" " execution duration in seconds that is considered \"slow\"." msgstr "" "执行时间超过 100 毫秒的回调会被写入日志。 :attr:`loop.slow_callback_duration` " "属性可用于设置以秒为单位的将被视为“缓慢”的最小执行持续时间。" #: ../../library/asyncio-dev.rst:64 msgid "Concurrency and Multithreading" msgstr "并发性和多线程" #: ../../library/asyncio-dev.rst:66 msgid "" "An event loop runs in a thread (typically the main thread) and executes all " "callbacks and Tasks in its thread. While a Task is running in the event " "loop, no other Tasks can run in the same thread. When a Task executes an " "``await`` expression, the running Task gets suspended, and the event loop " "executes the next Task." msgstr "" "事件循环在线程中运行 " "(通常是主线程),并在其线程中执行所有回调和任务。当一个任务在事件循环中运行时,没有其他任务可以在同一个线程中运行。当一个任务执行一个 " "``await`` 表达式时,正在运行的任务被挂起,事件循环执行下一个任务。" #: ../../library/asyncio-dev.rst:72 msgid "" "To schedule a :term:`callback` from another OS thread, the " ":meth:`loop.call_soon_threadsafe` method should be used. Example::" msgstr "" "要调度来自另一 OS 线程的 :term:`callback`,应该使用 :meth:`loop.call_soon_threadsafe` 方法。 " "例如::" #: ../../library/asyncio-dev.rst:75 msgid "loop.call_soon_threadsafe(callback, *args)" msgstr "loop.call_soon_threadsafe(callback, *args)" #: ../../library/asyncio-dev.rst:77 msgid "" "Almost all asyncio objects are not thread safe, which is typically not a " "problem unless there is code that works with them from outside of a Task or " "a callback. If there's a need for such code to call a low-level asyncio " "API, the :meth:`loop.call_soon_threadsafe` method should be used, e.g.::" msgstr "" "几乎所有异步对象都不是线程安全的,这通常不是问题,除非在任务或回调函数之外有代码可以使用它们。如果需要这样的代码来调用低级异步 API,应该使用 " ":meth:`loop.call_soon_threadsafe` 方法,例如::" #: ../../library/asyncio-dev.rst:83 msgid "loop.call_soon_threadsafe(fut.cancel)" msgstr "loop.call_soon_threadsafe(fut.cancel)" #: ../../library/asyncio-dev.rst:85 msgid "" "To schedule a coroutine object from a different OS thread, the " ":func:`run_coroutine_threadsafe` function should be used. It returns a " ":class:`concurrent.futures.Future` to access the result::" msgstr "" "要从不同的 OS 线程调度一个协程对象,应该使用 :func:`run_coroutine_threadsafe` 函数。它返回一个 " ":class:`concurrent.futures.Future`。查询结果::" #: ../../library/asyncio-dev.rst:89 msgid "" "async def coro_func():\n" " return await asyncio.sleep(1, 42)\n" "\n" "# Later in another OS thread:\n" "\n" "future = asyncio.run_coroutine_threadsafe(coro_func(), loop)\n" "# Wait for the result:\n" "result = future.result()" msgstr "" "async def coro_func():\n" " return await asyncio.sleep(1, 42)\n" "\n" "# 随后在另一个 OS 线程中:\n" "\n" "future = asyncio.run_coroutine_threadsafe(coro_func(), loop)\n" "# 等待结果:\n" "result = future.result()" #: ../../library/asyncio-dev.rst:98 msgid "To handle signals the event loop must be run in the main thread." msgstr "为了能处理信号,事件循环必须在主线程中运行。" #: ../../library/asyncio-dev.rst:101 msgid "" "The :meth:`loop.run_in_executor` method can be used with a " ":class:`concurrent.futures.ThreadPoolExecutor` or " ":class:`~concurrent.futures.InterpreterPoolExecutor` to execute blocking " "code in a different OS thread without blocking the OS thread that the event " "loop runs in." msgstr "" ":meth:`loop.run_in_executor` 方法可以配合 " ":class:`concurrent.futures.ThreadPoolExecutor` 或 " ":class:`~concurrent.futures.InterpreterPoolExecutor` 使用以在不同的 OS " "线程中执行阻塞型的代码而不会阻塞事件循环运行所在的 OS 线程。" #: ../../library/asyncio-dev.rst:107 msgid "" "There is currently no way to schedule coroutines or callbacks directly from " "a different process (such as one started with :mod:`multiprocessing`). The " ":ref:`asyncio-event-loop-methods` section lists APIs that can read from " "pipes and watch file descriptors without blocking the event loop. In " "addition, asyncio's :ref:`Subprocess ` APIs provide a " "way to start a process and communicate with it from the event loop. Lastly, " "the aforementioned :meth:`loop.run_in_executor` method can also be used with" " a :class:`concurrent.futures.ProcessPoolExecutor` to execute code in a " "different process." msgstr "" "目前没有办法直接从另一个进程(如使用 :mod:`multiprocessing` 启动的进程)安排协程或回调。 :ref:`asyncio-" "event-loop-methods` 小节列出了一些可以从管道读取并监视文件描述符而不会阻塞事件循环的 API。此外,asyncio 的 " ":ref:`子进程 ` API 提供了一种启动进程并在事件循环中与其通信的办法。最后,之前提到的 " ":meth:`loop.run_in_executor` 方法也可以配合 " ":class:`concurrent.futures.ProcessPoolExecutor` 使用以在另一个进程中执行代码。" #: ../../library/asyncio-dev.rst:121 msgid "Running Blocking Code" msgstr "运行阻塞的代码" #: ../../library/asyncio-dev.rst:123 msgid "" "Blocking (CPU-bound) code should not be called directly. For example, if a " "function performs a CPU-intensive calculation for 1 second, all concurrent " "asyncio Tasks and IO operations would be delayed by 1 second." msgstr "" "不应该直接调用阻塞 ( CPU 绑定) 代码。例如,如果一个函数执行 1 秒的 CPU 密集型计算,那么所有并发异步任务和 IO 操作都将延迟 1 秒。" #: ../../library/asyncio-dev.rst:128 msgid "" "An executor can be used to run a task in a different thread, including in a " "different interpreter, or even in a different process to avoid blocking the " "OS thread with the event loop. See the :meth:`loop.run_in_executor` method " "for more details." msgstr "" "可以使用执行器让任务运行在不同的线程中,包括不同的解释器中,或者甚至在不同的进程中以避免阻塞事件循环所在的 OS 线程。请参阅 " ":meth:`loop.run_in_executor` 方法了解详情。" #: ../../library/asyncio-dev.rst:138 msgid "Logging" msgstr "日志记录" #: ../../library/asyncio-dev.rst:140 msgid "" "asyncio uses the :mod:`logging` module and all logging is performed via the " "``\"asyncio\"`` logger." msgstr "asyncio 使用 :mod:`logging` 模块,所有日志记录都是通过 ``\"asyncio\"`` logger 执行的。" #: ../../library/asyncio-dev.rst:143 msgid "" "The default log level is :py:const:`logging.INFO`, which can be easily " "adjusted::" msgstr "默认的日志级别是 :py:const:`logging.INFO`,它可以被方便地调整::" #: ../../library/asyncio-dev.rst:146 msgid "logging.getLogger(\"asyncio\").setLevel(logging.WARNING)" msgstr "logging.getLogger(\"asyncio\").setLevel(logging.WARNING)" #: ../../library/asyncio-dev.rst:149 msgid "" "Network logging can block the event loop. It is recommended to use a " "separate thread for handling logs or use non-blocking IO. For example, see " ":ref:`blocking-handlers`." msgstr "" "网络日志会阻塞事件循环。建议使用一个单独线程来处理日志或者使用非阻塞式 IO。例如,可以参阅 :ref:`blocking-handlers`。" #: ../../library/asyncio-dev.rst:157 msgid "Detect never-awaited coroutines" msgstr "检测从未被等待的协程" #: ../../library/asyncio-dev.rst:159 msgid "" "When a coroutine function is called, but not awaited (e.g. ``coro()`` " "instead of ``await coro()``) or the coroutine is not scheduled with " ":meth:`asyncio.create_task`, asyncio will emit a :exc:`RuntimeWarning`::" msgstr "" "当协程函数被调用而不是被等待时 (即执行 ``coro()`` 而不是 ``await coro()``) 或者协程没有通过 " ":meth:`asyncio.create_task` 被排入计划日程,asyncio 将会发出一条 :exc:`RuntimeWarning`::" #: ../../library/asyncio-dev.rst:164 msgid "" "import asyncio\n" "\n" "async def test():\n" " print(\"never scheduled\")\n" "\n" "async def main():\n" " test()\n" "\n" "asyncio.run(main())" msgstr "" "import asyncio\n" "\n" "async def test():\n" " print(\"never scheduled\")\n" "\n" "async def main():\n" " test()\n" "\n" "asyncio.run(main())" #: ../../library/asyncio-dev.rst:174 ../../library/asyncio-dev.rst:219 #: ../../library/asyncio-dev.rst:393 ../../library/asyncio-dev.rst:450 msgid "Output::" msgstr "输出::" #: ../../library/asyncio-dev.rst:176 msgid "" "test.py:7: RuntimeWarning: coroutine 'test' was never awaited\n" " test()" msgstr "" "test.py:7: RuntimeWarning: coroutine 'test' was never awaited\n" " test()" #: ../../library/asyncio-dev.rst:179 ../../library/asyncio-dev.rst:235 msgid "Output in debug mode::" msgstr "调试模式的输出::" #: ../../library/asyncio-dev.rst:181 msgid "" "test.py:7: RuntimeWarning: coroutine 'test' was never awaited\n" "Coroutine created at (most recent call last)\n" " File \"../t.py\", line 9, in \n" " asyncio.run(main(), debug=True)\n" "\n" " < .. >\n" "\n" " File \"../t.py\", line 7, in main\n" " test()\n" " test()" msgstr "" "test.py:7: RuntimeWarning: coroutine 'test' was never awaited\n" "Coroutine created at (most recent call last)\n" " File \"../t.py\", line 9, in \n" " asyncio.run(main(), debug=True)\n" "\n" " < .. >\n" "\n" " File \"../t.py\", line 7, in main\n" " test()\n" " test()" #: ../../library/asyncio-dev.rst:192 msgid "" "The usual fix is to either await the coroutine or call the " ":meth:`asyncio.create_task` function::" msgstr "通常的修复方法是等待协程或者调用 :meth:`asyncio.create_task` 函数::" #: ../../library/asyncio-dev.rst:195 msgid "" "async def main():\n" " await test()" msgstr "" "async def main():\n" " await test()" #: ../../library/asyncio-dev.rst:200 msgid "Detect never-retrieved exceptions" msgstr "检测从未被获取的异常" #: ../../library/asyncio-dev.rst:202 msgid "" "If a :meth:`Future.set_exception` is called but the Future object is never " "awaited on, the exception would never be propagated to the user code. In " "this case, asyncio would emit a log message when the Future object is " "garbage collected." msgstr "" "如果调用了 :meth:`Future.set_exception`,但 Future 对象从未被等待,异常将永远不会传播到用户代码。在这种情况下,当 " "Future 对象被垃圾收集时,asyncio 将发出一条日志消息。" #: ../../library/asyncio-dev.rst:207 msgid "Example of an unhandled exception::" msgstr "未处理异常的例子::" #: ../../library/asyncio-dev.rst:209 msgid "" "import asyncio\n" "\n" "async def bug():\n" " raise Exception(\"not consumed\")\n" "\n" "async def main():\n" " asyncio.create_task(bug())\n" "\n" "asyncio.run(main())" msgstr "" "import asyncio\n" "\n" "async def bug():\n" " raise Exception(\"not consumed\")\n" "\n" "async def main():\n" " asyncio.create_task(bug())\n" "\n" "asyncio.run(main())" #: ../../library/asyncio-dev.rst:221 msgid "" "Task exception was never retrieved\n" "future: \n" " exception=Exception('not consumed')>\n" "\n" "Traceback (most recent call last):\n" " File \"test.py\", line 4, in bug\n" " raise Exception(\"not consumed\")\n" "Exception: not consumed" msgstr "" "Task exception was never retrieved\n" "future: \n" " exception=Exception('not consumed')>\n" "\n" "Traceback (most recent call last):\n" " File \"test.py\", line 4, in bug\n" " raise Exception(\"not consumed\")\n" "Exception: not consumed" #: ../../library/asyncio-dev.rst:230 msgid "" ":ref:`Enable the debug mode ` to get the traceback where" " the task was created::" msgstr ":ref:`激活调试模式 ` 以获取任务创建处的跟踪信息::" #: ../../library/asyncio-dev.rst:233 msgid "asyncio.run(main(), debug=True)" msgstr "asyncio.run(main(), debug=True)" #: ../../library/asyncio-dev.rst:237 msgid "" "Task exception was never retrieved\n" "future: \n" " exception=Exception('not consumed') created at asyncio/tasks.py:321>\n" "\n" "source_traceback: Object created at (most recent call last):\n" " File \"../t.py\", line 9, in \n" " asyncio.run(main(), debug=True)\n" "\n" "< .. >\n" "\n" "Traceback (most recent call last):\n" " File \"../t.py\", line 4, in bug\n" " raise Exception(\"not consumed\")\n" "Exception: not consumed" msgstr "" "Task exception was never retrieved\n" "future: \n" " exception=Exception('not consumed') created at asyncio/tasks.py:321>\n" "\n" "source_traceback: Object created at (most recent call last):\n" " File \"../t.py\", line 9, in \n" " asyncio.run(main(), debug=True)\n" "\n" "< .. >\n" "\n" "Traceback (most recent call last):\n" " File \"../t.py\", line 4, in bug\n" " raise Exception(\"not consumed\")\n" "Exception: not consumed" #: ../../library/asyncio-dev.rst:254 msgid "Asynchronous generators best practices" msgstr "异步生成器最佳实践" #: ../../library/asyncio-dev.rst:256 msgid "" "Writing correct and efficient asyncio code requires awareness of certain " "pitfalls. This section outlines essential best practices that can save you " "hours of debugging." msgstr "要编写正确且高效的 asyncio 代码就必须注意某些陷阱。 本节概述了可为您节省大量调试时间的关键最佳实践。" #: ../../library/asyncio-dev.rst:261 msgid "Close asynchronous generators explicitly" msgstr "显式地关闭异步生成器" #: ../../library/asyncio-dev.rst:263 msgid "" "It is recommended to manually close the :term:`asynchronous generator " "`. If a generator exits early - for " "example, due to an exception raised in the body of an ``async for`` loop - " "its asynchronous cleanup code may run in an unexpected context. This can " "occur after the tasks it depends on have completed, or during the event loop" " shutdown when the async-generator's garbage collection hook is called." msgstr "" "建议手动关闭 :term:`异步生成器 `。 如果一个生成器过早关闭 —— " "例如,由于在 ``async for`` 循环体中引发了异常 —— 它的异步清理代码可能会在非预期的上下文中运行。 " "这可能发生在它所依赖的任务完成之后,或是在异步生成器的垃圾收集钩子被调用时事件循环关闭期间。" #: ../../library/asyncio-dev.rst:271 msgid "" "To avoid this, explicitly close the generator by calling its " ":meth:`~agen.aclose` method, or use the :func:`contextlib.aclosing` context " "manager::" msgstr "" "要避免此问题,请通过调用生成器的 :meth:`~agen.aclose` 方法显式地关闭它,或是使用 " ":func:`contextlib.aclosing` 上下文管理器::" #: ../../library/asyncio-dev.rst:275 msgid "" "import asyncio\n" "import contextlib\n" "\n" "async def gen():\n" " yield 1\n" " yield 2\n" "\n" "async def func():\n" " async with contextlib.aclosing(gen()) as g:\n" " async for x in g:\n" " break # Don't iterate until the end\n" "\n" "asyncio.run(func())" msgstr "" "import asyncio\n" "import contextlib\n" "\n" "async def gen():\n" " yield 1\n" " yield 2\n" "\n" "async def func():\n" " async with contextlib.aclosing(gen()) as g:\n" " async for x in g:\n" " break # 不迭代一直到结束\n" "\n" "asyncio.run(func())" #: ../../library/asyncio-dev.rst:289 msgid "" "As noted above, the cleanup code for these asynchronous generators is " "deferred. The following example demonstrates that the finalization of an " "asynchronous generator can occur in an unexpected order::" msgstr "如上所述,这些异步生成器的清理代码会延迟执行。 下面的例子显示异步生成器的最终化可能会以非预期的顺序发生::" #: ../../library/asyncio-dev.rst:293 msgid "" "import asyncio\n" "work_done = False\n" "\n" "async def cursor():\n" " try:\n" " yield 1\n" " finally:\n" " assert work_done\n" "\n" "async def rows():\n" " global work_done\n" " try:\n" " yield 2\n" " finally:\n" " await asyncio.sleep(0.1) # imitate some async work\n" " work_done = True\n" "\n" "\n" "async def main():\n" " async for c in cursor():\n" " async for r in rows():\n" " break\n" " break\n" "\n" "asyncio.run(main())" msgstr "" #: ../../library/asyncio-dev.rst:319 msgid "For this example, we get the following output::" msgstr "对于这个例子,我们将得到以下输出::" #: ../../library/asyncio-dev.rst:321 msgid "" "unhandled exception during asyncio.run() shutdown\n" "task: ()> exception=AssertionError()>\n" "Traceback (most recent call last):\n" " File \"example.py\", line 6, in cursor\n" " yield 1\n" "asyncio.exceptions.CancelledError\n" "\n" "During handling of the above exception, another exception occurred:\n" "\n" "Traceback (most recent call last):\n" " File \"example.py\", line 8, in cursor\n" " assert work_done\n" " ^^^^^^^^^\n" "AssertionError" msgstr "" "unhandled exception during asyncio.run() shutdown\n" "task: ()> exception=AssertionError()>\n" "Traceback (most recent call last):\n" " File \"example.py\", line 6, in cursor\n" " yield 1\n" "asyncio.exceptions.CancelledError\n" "\n" "During handling of the above exception, another exception occurred:\n" "\n" "Traceback (most recent call last):\n" " File \"example.py\", line 8, in cursor\n" " assert work_done\n" " ^^^^^^^^^\n" "AssertionError" #: ../../library/asyncio-dev.rst:336 msgid "" "The ``cursor()`` asynchronous generator was finalized before the ``rows`` " "generator - an unexpected behavior." msgstr "``cursor()`` 异步生成器会在 ``rows`` 生成器之前执行最终化 —— 这是非预期的行为。" #: ../../library/asyncio-dev.rst:339 msgid "" "The example can be fixed by explicitly closing the ``cursor`` and ``rows`` " "async-generators::" msgstr "这个例子可通过显式地关闭 ``cursor`` 和 ``rows`` 异步生成器来修正问题::" #: ../../library/asyncio-dev.rst:342 msgid "" "async def main():\n" " async with contextlib.aclosing(cursor()) as cursor_gen:\n" " async for c in cursor_gen:\n" " async with contextlib.aclosing(rows()) as rows_gen:\n" " async for r in rows_gen:\n" " break\n" " break" msgstr "" "async def main():\n" " async with contextlib.aclosing(cursor()) as cursor_gen:\n" " async for c in cursor_gen:\n" " async with contextlib.aclosing(rows()) as rows_gen:\n" " async for r in rows_gen:\n" " break\n" " break" #: ../../library/asyncio-dev.rst:352 msgid "Create asynchronous generators only when the event loop is running" msgstr "仅在事件循环正在运行时创建异步生成器" #: ../../library/asyncio-dev.rst:354 msgid "" "It is recommended to create :term:`asynchronous generators ` only after the event loop has been created." msgstr "推荐做法是只在事件循环已被创建之后才创建 :term:`异步生成器 `。" #: ../../library/asyncio-dev.rst:358 msgid "" "To ensure that asynchronous generators close reliably, the event loop uses " "the :func:`sys.set_asyncgen_hooks` function to register callback functions. " "These callbacks update the list of running asynchronous generators to keep " "it in a consistent state." msgstr "" #: ../../library/asyncio-dev.rst:363 msgid "" "When the :meth:`loop.shutdown_asyncgens() `" " function is called, the running generators are stopped gracefully and the " "list is cleared." msgstr "" #: ../../library/asyncio-dev.rst:367 msgid "" "The asynchronous generator invokes the corresponding system hook during its " "first iteration. At the same time, the generator records that the hook has " "been called and does not call it again." msgstr "" #: ../../library/asyncio-dev.rst:371 msgid "" "Therefore, if iteration begins before the event loop is created, the event " "loop will not be able to add the generator to its list of active generators " "because the hooks are set after the generator attempts to call them. " "Consequently, the event loop will not be able to terminate the generator if " "necessary." msgstr "" #: ../../library/asyncio-dev.rst:377 msgid "Consider the following example::" msgstr "比如下面的例子::" #: ../../library/asyncio-dev.rst:379 msgid "" "import asyncio\n" "\n" "async def agenfn():\n" " try:\n" " yield 10\n" " finally:\n" " await asyncio.sleep(0)\n" "\n" "\n" "with asyncio.Runner() as runner:\n" " agen = agenfn()\n" " print(runner.run(anext(agen)))\n" " del agen" msgstr "" "import asyncio\n" "\n" "async def agenfn():\n" " try:\n" " yield 10\n" " finally:\n" " await asyncio.sleep(0)\n" "\n" "\n" "with asyncio.Runner() as runner:\n" " agen = agenfn()\n" " print(runner.run(anext(agen)))\n" " del agen" #: ../../library/asyncio-dev.rst:395 msgid "" "10\n" "Exception ignored while closing generator :\n" "Traceback (most recent call last):\n" " File \"example.py\", line 13, in \n" " del agen\n" " ^^^^\n" "RuntimeError: async generator ignored GeneratorExit" msgstr "" "10\n" "Exception ignored while closing generator :\n" "Traceback (most recent call last):\n" " File \"example.py\", line 13, in \n" " del agen\n" " ^^^^\n" "RuntimeError: async generator ignored GeneratorExit" #: ../../library/asyncio-dev.rst:403 msgid "This example can be fixed as follows::" msgstr "该示例可用以下方式修复::" #: ../../library/asyncio-dev.rst:405 msgid "" "import asyncio\n" "\n" "async def agenfn():\n" " try:\n" " yield 10\n" " finally:\n" " await asyncio.sleep(0)\n" "\n" "async def main():\n" " agen = agenfn()\n" " print(await anext(agen))\n" " del agen\n" "\n" "asyncio.run(main())" msgstr "" "import asyncio\n" "\n" "async def agenfn():\n" " try:\n" " yield 10\n" " finally:\n" " await asyncio.sleep(0)\n" "\n" "async def main():\n" " agen = agenfn()\n" " print(await anext(agen))\n" " del agen\n" "\n" "asyncio.run(main())" #: ../../library/asyncio-dev.rst:422 msgid "Avoid concurrent iteration and closure of the same generator" msgstr "避免同一迭代器的并发迭代和闭包" #: ../../library/asyncio-dev.rst:424 msgid "" "Async generators may be reentered while another :meth:`~agen.__anext__` / " ":meth:`~agen.athrow` / :meth:`~agen.aclose` call is in progress. This may " "lead to an inconsistent state of the async generator and can cause errors." msgstr "" "异步生成器可以在其他 :meth:`~agen.__anext__` / :meth:`~agen.athrow` / " ":meth:`~agen.aclose` 调用正在进行时重新进入。 这可能导致异步生成器状态不一致并造成错误。" #: ../../library/asyncio-dev.rst:429 msgid "Let's consider the following example::" msgstr "" #: ../../library/asyncio-dev.rst:431 msgid "" "import asyncio\n" "\n" "async def consumer():\n" " for idx in range(100):\n" " await asyncio.sleep(0)\n" " message = yield idx\n" " print('received', message)\n" "\n" "async def amain():\n" " agenerator = consumer()\n" " await agenerator.asend(None)\n" "\n" " fa = asyncio.create_task(agenerator.asend('A'))\n" " fb = asyncio.create_task(agenerator.asend('B'))\n" " await fa\n" " await fb\n" "\n" "asyncio.run(amain())" msgstr "" #: ../../library/asyncio-dev.rst:452 msgid "" "received A\n" "Traceback (most recent call last):\n" " File \"test.py\", line 38, in \n" " asyncio.run(amain())\n" " ~~~~~~~~~~~^^^^^^^^^\n" " File \"Lib/asyncio/runners.py\", line 204, in run\n" " return runner.run(main)\n" " ~~~~~~~~~~^^^^^^\n" " File \"Lib/asyncio/runners.py\", line 127, in run\n" " return self._loop.run_until_complete(task)\n" " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^\n" " File \"Lib/asyncio/base_events.py\", line 719, in run_until_complete\n" " return future.result()\n" " ~~~~~~~~~~~~~^^\n" " File \"test.py\", line 36, in amain\n" " await fb\n" "RuntimeError: anext(): asynchronous generator is already running" msgstr "" #: ../../library/asyncio-dev.rst:471 msgid "" "Therefore, it is recommended to avoid using asynchronous generators in " "parallel tasks or across multiple event loops." msgstr ""