gpt4 book ai didi

python - 将函数变成生成器

转载 作者:行者123 更新时间:2023-11-28 22:35:13 25 4
gpt4 key购买 nike

通过以下方法,我可以列出我的 Google 云端硬盘帐户中的所有文件:

def listAllFiles(self):
result = [];
page_token = None;

while True:
try:
param = {"q" : "trashed=false", "orderBy": "createdTime"};
if page_token: param['pageToken'] = page_token;
files = self.service.files().list(**param).execute();

result.extend(files["files"]);
page_token = files.get('nextPageToken');
if not page_token: break;

except errors.HttpError as error:
print('An error occurred:', error);
break; # Exit with empty list

return result;

为了更好的运行时间,我想从此方法返回一个生成器。我是 Python 的新手,所以我不知道该怎么做。

文件服务的执行方法总是返回 100 个项目,如果它也返回一个 page_token,则还有更多项目要获取。如果我可以遍历生成器以获取已经获取的项目,同时从服务中获取下一个项目,那就太好了。我希望你明白我的意思...

这可能吗?我必须如何重写此方法才能获得所描述的功能?

最佳答案

您可以通过简单地生成单个文件路径来重写您的函数以充当生成器。

未经测试:

def listAllFiles(self):
result = []
page_token = None

while True:
try:
param = {"q" : "trashed=false", "orderBy": "createdTime"}
if page_token:
param['pageToken'] = page_token
files = self.service.files().list(**param).execute()

# call future to load the next bunch of files here!
for f in files["files"]:
yield f
page_token = files.get('nextPageToken')
if not page_token: break

except errors.HttpError as error:
print('An error occurred:', error)
break

如果您不进一步并行化,请使用 chapelo's answer反而。产生所有可用文件的列表将允许协程继续,从而开始同时获取下一个文件列表。


用 futures 预加载下一堆

现在,您仍然没有同时加载下一批文件。为此,如上面的代码所述,您可以执行 future。已经同时收集下一个文件列表。当你的 yielded item 被消费时(并且你的函数继续执行)你会展望你的 future ,看看结果是否已经存在。如果没有,您必须等待(和以前一样)直到结果到达。

因为我没有你的代码,所以我不能说这段代码是否有效(或者甚至在语法上是否正确),但你可以将它作为起点:

import concurrent.futures

def load_next_page(self, page_token=None):
param = {"q" : "trashed=false", "orderBy": "createdTime"}
if page_token:
param['pageToken'] = page_token

result = None
try:
files = self.service.files().list(**param).execute()
result = (files.get('nextPageToken'), files["files"])
except errors.HttpError as error:
print('An error occurred:', error)
return result

def listAllFiles(self):
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:

future = executor.submit(self.load_next_page, 60)

while future:
try:
result = future.result()
future = None
if not result:
break
(next_page_token, files) = result
except Exception as error:
print('An error occured:', error)
break
if next_page_token:
future = executor.submit(self.load_next_page, next_page_token, 60)
# yield from files
for f in files:
yield f

使用队列的生产者/消费者并行化

评论中也提到了另一种选择,即使用 Queue .您可以修改您的函数以返回一个队列,该队列由您的函数生成的线程填充。这应该比仅预加载下一个列表更快,但也会产生更高的实现开销。

我个人建议选择 future 的路径——如果性能足够的话。

关于python - 将函数变成生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38424046/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com