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はずです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)

もう 1 つ確認しなければならないことは、Python がモジュールのロード方法を認識していることです。パッケージをインストールした場合、これは自動的に行われますが、開発中は通常そうではありません。したがって、開発中は、開発モジュールを見つけられるようにする必要もあります。

最も簡単な方法 (ただしあまりきれいではありません) は、 を使用することsys.path.append('the directory containing tools and engine')です。toolsもう 1 つの方法 (クリーン) は、 PYTHONPATH 環境変数を設定して、とを含む最上位ディレクトリを含めることですengine

于 2014-05-27T15:35:37.340 に答える