[英]C# and IronPython integration
我想簡單地使用C#中的io.py
來編寫文件,我使用以下代碼:
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
...
System.IO.Directory.SetCurrentDirectory(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
"\IronPython\Lib");
ScriptRuntime py = Python.CreateRuntime();
dynamic io = py.UseFile("io.py");
dynamic f = io.open("tmp.txt", "w");
f.writelines("some text...");
f.close();
但是當我運行程序時,運行時給了我一個:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException告訴沒有writelines的重載接受參數'1'
似乎該方法不存在......但是在io.py
文檔中它存在。
PS同樣是close
方法!
任何的想法?
我只能告訴你如何使你的代碼工作,但是我對IronPython沒有多少經驗,也不知道為什么這樣做(雖然我試着去了解)。 首先,似乎io模塊以特殊方式處理,並且有特殊的(非動態)類。 當你執行io.open
返回的是PythonIOModule._IOBase
類的實例。 你可以做
var f = (PythonIOModule._IOBase) io.open("tmp.txt", "w");
並且親眼看看“writeline”方法(這是常規方法,而不是動態方法)接受CodeContext實例作為第一個參數,第二個參數是行。 有趣的是,這個類本身已經包含了CodeContext的字段,但是由於某種原因它是內部的,更糟糕的是 - writelines(和其他方法)本來可以使用CodeContext而不需要我們提供外部的。 為什么這樣做 - 我不知道。
因此,為了使您的代碼正常工作,我們必須在某處獲得CodeContext。 一種方法是通過反射來做到這一點:
var context = (CodeContext) f.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(f);
另一種方法是自己制作:
var languageContext = HostingHelpers.GetLanguageContext(engine);
var context = new ModuleContext(io._io, new PythonContext(languageContext.DomainManager, new Dictionary<string, object>())).GlobalContext;
這兩種方法都可以工作,程序將成功寫入文件。 完整的工作樣本:
static void Main(string[] args) {
System.IO.Directory.SetCurrentDirectory(@"G:\Python27\Lib");
var engine = Python.CreateEngine();
dynamic io = engine.ImportModule("io");
var f = (PythonIOModule._IOBase) io.open("tmp.txt", "w");
var languageContext = HostingHelpers.GetLanguageContext(engine);
var context = new ModuleContext(io._io, new PythonContext(languageContext.DomainManager, new Dictionary<string, object>())).GlobalContext;
f.writelines(context, "some text....");
f.close(context);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.