【问题标题】:Storing the values produced by a generator for multiple uses存储生成器生成的值以供多种用途
【发布时间】:2018-04-15 19:04:16
【问题描述】:

我正在开发一个程序,它将检查用户的硬盘驱动器是否有游戏,并显示计算机上安装的所有游戏的列表以及相关名称和路径。

我通过在 JSON 中创建一个数据库来实现这一点,该数据库包含每个游戏的名称和路径(程序在 linux 和 windows 上运行,因此数据库中有 4 个值:名称、windows_path、windows_steam_path、linux_path、linux_steam_path)*Steam路径是检查游戏是否使用steam云

"name",
    "Windows_path",
    "Windows_steam_path",
    "Linux_path",
    "Linux_sync_path"

我还需要为每个游戏创建一个“模板”,因此我为它们创建了一个类

class Game():
    def __init__(self, game_name, game_path, sync_path):
        self.name = game_name
        self.path = game_path
        self.sync_path = sync_path
    def to_dict(self):
        self.name
        self.path
        self.sync_path
        return {"name": self.name, "path": self.path, "sync_path": self.sync_path}

我还需要一个用户界面 Eel - https://github.com/ChrisKnott/Eel

Eel 拥有一个本地网络服务器,所以我将使用 HTML 文件来显示内容

<nav class="navbar navbar-expand-lg navbar-light bg-dark" Style="display:block; height:50px">
  <a href="../index.html" class="btn btn-info float-left">Home</a>
  <a href="userGuide.html" class="btn btn-info float-right">User Guide</a>
</nav>

<div id="game_database" class="row"></div>

现在我像这样从数据库中获取数据

save_database = json.load(open("database.json"))

def load_game(db_item):
    current_os = platform.system()
    path = ""
    sync_path = ""
    [name, win_path, win_sync, lin_path, lin_sync] = db_item
    if current_os == "Windows":
        sync_path = win_sync
        path = win_path
        print(path, sync_path)
    else:
        sync_path = lin_sync
        path = lin_path
        print(path, sync_path)
    print(Game(name, os.path.expanduser(path), os.path.expanduser(sync_path)))
    return Game(name, os.path.expanduser(path), os.path.expanduser(sync_path))

save_database = map(load_game, save_database)

并将数据传入字典

def get_all_in_database():
for game in save_database:
    game_dict = game.to_dict()
    yield game_dict

然后我使用 lodash 创建模板,使用 javascript 和 jquery 修改 html 并调用 python 函数(我不在这里发布代码,因为这已经是一个很大的问题)

当我转到我想要的页面时,它会调用 javascript 函数,该函数调用所有其他函数并通过模板等发送数据。一切正常,但只有一次。

如果我刷新页面或再次调用该函数,它应该显示游戏,但它没有;它给我的只是一个空列表[],因为当我将函数公开给javascript时,我列出(它))

[{'name': 'Portal 2', 'path': 'NFL', 'sync_path': '~./steam/steam/userdata/XXXXX/game/remote/'}]
Listing games
[]

我四处搜索并询问了一些朋友,发现 yield 是一个生成器,只迭代一次值并且它是不可重用的,所以我想它与此有关,但我也希望能够生成动态值并“保留”它们以供以后使用,因此由于我对 python 和一般编程的了解有限,我目前对如何进行有点迷茫

【问题讨论】:

  • list(get_all_in_database())?或者,如果您确实想要该列表,请不要以 yield 开头。
  • 但是返回它不会像使用 yield generator 那样即时生成值
  • 确实如此,但鉴于您希望它们都在列表中,这似乎没有那么有用。

标签: python dictionary yield


【解决方案1】:

感谢我的一个朋友,我找到了自己问题的答案(为 fabiosantoscode 鼓掌 - https://github.com/fabiosantoscode

正如你所看到的,当我最后从 json 导入数据库时​​

save_database = map(load_game, save_database)

如果我有的话,map 是一个生成器,太棒了

save_database = list(map(load_game, save_database))

我不必连续三天用头撞墙哈哈

感谢大家的关注!!

【讨论】:

  • Python 3 的引入,将map 从列表转换为迭代器,特别禁止list(map(...)):docs.python.org/3.0/whatsnew/…:“更好的解决方法通常是使用列表推导式".
  • 不知道我还是个初学者,但非常感谢您提供的信息,我一定会去看看!!
【解决方案2】:

get_all_in_database 函数中使用return 代替yield,并将它们添加到新列表中。

def get_all_in_database():
    newlist = []
    for game in save_database:
        newlist.append(game.to_dict())
    return newlist

【讨论】:

  • 那么它只会返回第一个游戏。
  • 反应太快了,会改一下
  • 哇,这行得通,但因为产量只有在我这样做时才有效def generated_games(): g = [] for game in save_database: g.append(game.to_dict()) return g
  • 控制台输出还是:[{'name': 'Portal 2', 'path': 'NFL', 'sync_path': '~./steam/steam/userdata/XXXXX/game/remote/'}] Listing games []
猜你喜欢
  • 2021-12-11
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 2012-05-30
相关资源
最近更新 更多