0

我正在开发一个游戏引擎,其中包括一个简单的 GUI 开发工具。GUI 工具允许用户定义各种实体和组件,然后可以将其保存在配置文件中。当游戏引擎运行时加载配置文件时,它可以确定如何创建各种实体和组件以供游戏使用。

对于配置文件保存机制,我使用的是 PyYAML。我遇到的问题源于这样一个事实,即序列化过程发生在一个模块中,该模块与通过 PyYAML 加载和解析文件的模块位于不同的目录中。

简化的串行器

import yaml

def save_config(context, file_name):
    config_file = file(file_name, 'w')
    # do some various processing on the context dict object
    yaml.dump(context, config_file)
    config_file.close()

这需要context对象,这是一个dict代表各种游戏对象的对象,并将其写入配置文件。这没有问题。

引擎中的简化反序列化器

import yaml

def load(file_name):
    config_file = open(file_name, 'r')
    context = yaml.load(config_file)
    return context

这就是问题发生的地方。在 上yaml.load(config_file),我会收到一个错误,因为它无法在某个模块上找到各种名称。我明白为什么会这样。例如,当我序列化配置文件时,它会将一个AssetComponent(引擎中的组件类型)列为 at engine.common.AssetComponent。但是,从反序列化器的角度来看,AssetComponent应该只是 at common.AssetComponent(因为反序列化代码本身存在于engine包中),因此无法在engine.

有没有办法在使用 PyYAML 进行序列化或反序列化时手动处理路径?我想确保它们都是从同一个“角度”发生的。

编辑: 以下显示有问题的配置文件可能是什么样子,然后是手动更正的配置的样子

有问题的

!!python/object/apply:collections.defaultdict
args: [!!python/name:__builtin__.dict ''] 
dictitems:
  assets:
  - !!python/object:common.Component
    component: !!python/object:engine.common.AssetComponent {file_name: ../content/sticksheet.png,
      surface: null}
    text: ../content/sticksheet.png
    type_name: AssetComponent

已更正

!!python/object/apply:collections.defaultdict
args: [!!python/name:__builtin__.dict ''] 
dictitems:
  assets:
  - !!python/object:tools.common.Component
    component: !!python/object:common.AssetComponent {file_name: ../content/sticksheet.png,
      surface: null}
    text: ../content/sticksheet.png
    type_name: AssetComponent
4

2 回答 2

0

您可以在 YAML 文档中显式声明对象的 Python 类型:

!!python/object:module_foo.ClassFoo {
    attr_foo: "spam",
    …,
}
于 2014-05-22T05:48:17.997 回答
0

你的问题在于你的包结构和你的__main__例程不匹配。包含您__main__遗嘱的模块位于一个包中,但它无法知道这一点。因此,您将使用相对于包含文件的位置__main__而不是相对于包的顶级结构的导入。

有关更长(可能更好)的解释,请参阅第 10 亿次相对进口。

那么,您该如何解决呢?

在包含__main__您的文件中:

from tools.common import Component
# instead of from common import Component

c = Component()
print yaml.dump(c)

您必须确保的另一件事是 python 将知道如何加载您的模块。如果您已经安装了软件包,这将自动完成,但在开发过程中通常不是这种情况。因此,在开发过程中,您还希望使您的开发模块可查找。

最简单的方法(但不是很干净)是使用sys.path.append('the directory containing tools and engine'). tools另一种方法(更清洁)是设置 PYTHONPATH 环境变量以包含包含and的顶级目录engine

于 2014-05-27T15:35:37.340 回答