[英]C# and IronPython integration
I want simply use io.py
from C# to write a file and I use the following code: 我想简单地使用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();
but when I run the program the runtime give me a: 但是当我运行程序时,运行时给了我一个:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException telling that no overload of writelines accept argument '1' Microsoft.CSharp.RuntimeBinder.RuntimeBinderException告诉没有writelines的重载接受参数'1'
it seems like that method doesn't exists... but into io.py
documentation it exists. 似乎该方法不存在......但是在
io.py
文档中它存在。
PS The same is for close
method!!! PS同样是
close
方法!
Any idea? 任何的想法?
I can only tell you how to make your code working, however I don't have much experience with IronPython and have no idea why it is done this way (though I try to learn that). 我只能告诉你如何使你的代码工作,但是我对IronPython没有多少经验,也不知道为什么这样做(虽然我试着去了解)。 First, it seems io module is treated in a special way and there is special (non-dynamic) class for that.
首先,似乎io模块以特殊方式处理,并且有特殊的(非动态)类。 When you do
io.open
what is returned is instance of PythonIOModule._IOBase
class. 当你执行
io.open
返回的是PythonIOModule._IOBase
类的实例。 You can do 你可以做
var f = (PythonIOModule._IOBase) io.open("tmp.txt", "w");
And see for yourself that "writeline" method (which is regular method, not a dynamic one) accepts CodeContext instance as first argument, and second argument is lines. 并且亲眼看看“writeline”方法(这是常规方法,而不是动态方法)接受CodeContext实例作为第一个参数,第二个参数是行。 Interesting that this class itself already contains field with that CodeContext, but it is made internal for some reason, and what is even worse - writelines (and other methods) could have been using that CodeContext and not require us to provide external one.
有趣的是,这个类本身已经包含了CodeContext的字段,但是由于某种原因它是内部的,更糟糕的是 - writelines(和其他方法)本来可以使用CodeContext而不需要我们提供外部的。 Why is it done like this - I have no idea.
为什么这样做 - 我不知道。
So to make your code working, we have to get CodeContext somewhere. 因此,为了使您的代码正常工作,我们必须在某处获得CodeContext。 One way is do that via reflection:
一种方法是通过反射来做到这一点:
var context = (CodeContext) f.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(f);
Another way is to craft it yourself: 另一种方法是自己制作:
var languageContext = HostingHelpers.GetLanguageContext(engine);
var context = new ModuleContext(io._io, new PythonContext(languageContext.DomainManager, new Dictionary<string, object>())).GlobalContext;
Both methods will work and program will successfully write to a file. 这两种方法都可以工作,程序将成功写入文件。 Full working sample:
完整的工作样本:
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.