的文档asyncio.create_task()指出以下警告:
重要提示:保存对此函数结果的引用,以避免任务在执行过程中消失。(来源)
我的问题是:这是真的吗?
我有几个 IO 绑定的“即发即忘”任务,我想asyncio通过使用将它们提交到事件循环来同时运行这些任务asyncio.create_task()。但是,我并不真正关心协程的返回值,或者即使它们运行成功,只关心它们最终会运行。一种用例是将“昂贵”计算中的数据写回 Redis 数据库。如果 Redis 可用,那就太好了。如果没有,哦,好吧,没有坏处。这就是为什么我不想/不需要await这些任务。
这是一个通用示例:
import asyncio
async def fire_and_forget_coro():
"""Some random coroutine waiting for IO to complete."""
print('in fire_and_forget_coro()')
await asyncio.sleep(1.0)
print('fire_and_forget_coro() done')
async def async_main():
"""Main entry point of asyncio application."""
print('in async_main()')
n = 3
for _ in range(n):
# create_task() does not block, returns immediately.
# Note: We do NOT save a reference to the submitted task here! …Run Code Online (Sandbox Code Playgroud) 这是我的代码的简化版本:
main是一个在第二次迭代后停止的协程。
get_numbers是一个异步生成器,它生成数字,但位于异步上下文管理器中。
import asyncio
class MyContextManager:
async def __aenter__(self):
print("Enter to the Context Manager...")
return self
async def __aexit__(self, exc_type, exc_value, exc_tb):
print(exc_type)
print("Exit from the Context Manager...")
await asyncio.sleep(1)
print("This line is not executed") # <-------------------
await asyncio.sleep(1)
async def get_numbers():
async with MyContextManager():
for i in range(30):
yield i
async def main():
async for i in get_numbers():
print(i)
if i == 1:
break
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
输出是:
Enter to the Context Manager...
0
1
<class 'asyncio.exceptions.CancelledError'>
Exit …Run Code Online (Sandbox Code Playgroud) python asynchronous contextmanager python-3.x python-asyncio
我必须将product_id(这是一个字符串)传递到视图中。在那里我必须根据产品 ID 进行一些数据库操作。如何在该视图中获取该产品 ID?实际上类ProductDetailConfiguration视图中的参数应该是什么?现在我路过viewsets.ModelViewSet。实际上,这个 API 调用并不与任何模型完全相关。
# urls.py
url(r'^product-configuration/(?P<product_id>[\w-]+)/$', views.ProductDetailConfiguration, name='product-configuration'),
Run Code Online (Sandbox Code Playgroud)
# 视图.py
class ProductDetailConfiguration(viewsets.ModelViewSet):
queryset = Product.objects.all()
def get_queryset(self, **kwargs):
queryset = Product.objects.all()
product_id = self.request.get('product_id', None)
#filter query set based on the product_id
return queryset
serializer_class = ProductConfigurationSerializer
Run Code Online (Sandbox Code Playgroud) python django django-models django-views django-rest-framework
有这个简单的代码:
import asyncio
async def main():
f = asyncio.Future()
await f
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
协程(此处main)可以等待 Future 对象。它基本上会被阻止,直到f有结果或设置异常,或者直到它们被取消。
出于好奇,我想知道“这种等待是如何发生的”?我具体检查了Task.py的 Python 实现def __step()。
在最简单的形式中,快乐的情况下,当返回的result是 Future 时,它是:
.
.
result = coro.send(None)
.
.
blocking = getattr(result, '_asyncio_future_blocking', None)
.
.
if blocking: # So `result` is a Future with `_asyncio_future_blocking == True`
result._asyncio_future_blocking = False
result.add_done_callback(self.__wakeup, context=self._context)
self._fut_waiter = result
if self._must_cancel:
if self._fut_waiter.cancel(msg=self._cancel_message):
self._must_cancel = False
Run Code Online (Sandbox Code Playgroud)
我从本节中得到了所有其他答案(例如当它result是裸露的yield或CancellationError发生时等等),除了这个! …
我正在尝试使用 termux (python 3.5) 安装特定版本的 python,但它正在下载最新版本 (Python 3.7.2-1)。有什么办法可以指定安装哪个版本吗?
我使用的命令非常简单,但我还没有找到任何方法在任何地方指定版本
pkg install python
Run Code Online (Sandbox Code Playgroud) 这是下面给出的代码。
k = [1, 8, 15]
g = (x for x in k if k.count(x) > 0)
k = [2, 8, 22]
print(list(g))
Run Code Online (Sandbox Code Playgroud)
我得到的输出为 [8],但它应该是 [1,8,15],对吗?因为每个元素至少出现一次。
对答案有什么合理的解释吗?
我曾经pip install fastapi在虚拟环境中的终端中下载它,但是当我尝试从中导入时,它显示为丢失的导入。
我正在阅读 python 文档和 peps,但找不到答案。
python中的泛型是通过给类对象添加下标来实现的。list[str]是一个列表,其中所有元素都是字符串。
此行为是通过实现一个特殊的(dunder)类方法来实现的,__class_getitem__根据文档所述,该方法应返回 GenericAlias。
一个例子:
class MyGeneric:
def __class_getitem__(cls, key):
# implement generics
...
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很奇怪,因为文档还显示了一些类似于解释器在面对下标对象时所做的代码,并显示__getitem__在对象的元类和__class_getitem__对象本身上定义总是选择元类' __getitem__。这意味着无需在语言中引入新的特殊方法即可实现与上述功能相同的类。
具有相同行为的类的示例:
class GenericMeta(type):
def __getitem__(self, key):
# implement generics
...
class MyGeneric(metaclass=GenericMeta):
...
Run Code Online (Sandbox Code Playgroud)
稍后文档还显示了 s 的示例,Enum使用元类的 a作为 a未被调用的__getitem__示例。__class_getitem__
我的问题是为什么__class_getitem__首先引入类方法?
它似乎与元类做了完全相同的事情,__getitem__但增加了复杂性,并且需要在解释器中添加额外的代码来决定调用哪个方法。所有这些都没有额外的好处,因为定义两者每次都会简单地调用相同的方法,除非专门调用 dunder 方法(通常不应该这样做)。
我知道不鼓励以这种方式实现泛型。__class_getitem__一般方法是对已经定义类似的类进行子类化typing.Generic,但我仍然很好奇为什么以这种方式实现该功能。
我目前使用这段代码:
def f():
try:
f()
except RecursionError:
f()
try:
f()
except RecursionError:
f()
Run Code Online (Sandbox Code Playgroud)
这会立即导致致命的堆栈溢出。然而,我想知道是否有一种更简单、更Pythonic 的方法可以做到这一点。
我真的很喜欢 vscode 的 JSON 验证器。它可以捕获许多编辑器无法捕获的错误,因此我真的很想在预提交测试中使用它。为此,我希望有一个与它相当的 npm。
假设我正在检查这个 JSON 文件。
{
"a": "b",
"b": "c",
"c": "d",
}
Run Code Online (Sandbox Code Playgroud)
它后面有一个逗号,这是不允许的。然而,jsonlint,它似乎是最流行的 npm json linter 给出了错误:
Error: Parse error on line 4:
...b": "c", "c": "d",}
---------------------^
Expecting 'STRING', got '}'
Run Code Online (Sandbox Code Playgroud)
这可能要花我很长时间才能找到,而 vscode:
Trailing comma json(519) [4,11]
Run Code Online (Sandbox Code Playgroud)
这更容易阅读。
python ×9
asynchronous ×2
python-3.x ×2
async-await ×1
django ×1
django-views ×1
fastapi ×1
future ×1
import ×1
iterator ×1
json ×1
pylance ×1
python-3.7 ×1
task ×1
termux ×1