1

私が取り組んでいるプログラムを変更する方法として、IronPython を C# に埋め込んでいます。そのため、一度に使用する必要がある複数のファイルがあります。

        Code = "";
        Engine = Python.CreateEngine();
        Runtime = Engine.Runtime;
        var files = Directory.GetFiles("script", "*.py", SearchOption.AllDirectories);
        foreach (var tr in files.Select(file => new StreamReader(file)))
        {
            Code += "\n";
            Code += tr.ReadToEnd();
            tr.Close();
        }
        Scope = Engine.CreateScope();

        Engine.CreateScriptSourceFromString(AddImports(Code)).Execute(Scope);

これは /script 内のすべてのファイルを取得し、それらを 1 つの文字列に結合して、それらからスクリプト ソースを作成します。クラスがアルファベット順に継承されない場合、UnboundNameException が発生するため、これはもちろん欠陥のある方法です。

class bar(foo):
    pass

class foo():
    pass

通常の方法ですべてのファイルをコンパイルするにはどうすればよいですか?

4

1 に答える 1

3

コード/ファイルを pythonモジュールとして構造化し、それらをそのままインポートして使用すると、python ランタイムがインポートと依存関係を処理/解決します。メイン エントリ ポイントをA.pyとして含むプライマリ python ファイルがあるとします。

import B, C
foo = B.Foo()
bar = C.Bar()

foo.foo()
bar.bar(foo)

print("done")

このファイルは、B.pyおよびC.pyで定義されたモジュールBおよびCを使用します。

B.py:

class Foo:
    def foo(self):
        print("Foo.foo()")

C.py (モジュールCはモジュールBも使用/インポートすることに注意してください):

import B
class Bar:
    def bar(self, foo):
        print("Bar.bar()")

エンジンをセットアップしてすべてを実行するための .NET ボイラープレート ( A.pyB.py、およびC.pyが .NET バイナリと同じディレクトリまたはパス上に存在すると仮定) は次のようになります。

var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var source = engine.CreateScriptSourceFromFile("A.py");
source.Execute(scope);

A.py (メイン エントリ ポイントとして)のみをロードする必要があり、それ以外はすべてランタイムによって解決されることに注意してください。

スクリプトが複数のフォルダーに分割されている場合は、それに応じて検索パスを変更する必要がある場合があります。A.pyを除くすべてのファイルがスクリプトと呼ばれるフォルダーにあると仮定すると、次のようになります。

var paths = engine.GetSearchPaths();
paths.Add("scripts");
engine.SetSearchPaths(paths);

何らかの理由で、クラスを使用するときにモジュールの名前空間を避けたい場合は、* をインポートすることもできます。ユースケースによってはこれの方が簡単かもしれませんが、名前の衝突が発生する可能性があります (たとえば、ABの両方がクラスFooを定義する場合)。

from B import *
from C import *
foo = Foo()
bar = Bar()
于 2013-01-21T09:00:00.170 に答える