2010-01-26 20 views
10

Bu senaryoyu çalıştırmanın bir yolu var mı?Python komut dosyaları oluşturun ve yöntemleri arayın C#

Bir Python betiği var. O IronPython ile bu script çalıştırarak bir DLL yerleşik:

import clr 
clr.CompileModules("CompiledScript.dll", "script.py") 

gol C# kodu bu DLL yöntemlerini aramak. .NET Reflector, DLL'de bir sınıf olduğunu gösterir - DLRCashedCode ve ilgilendiğimiz yöntemler bu sınıfın özel statik yöntemleridir.

def scriptMethod(self, text): 
... 

DLL Onun gösterimidir: Örneğin:

, komut bir işlevi vardır

private static object scriptMethod(Closure closure1, PythonFunction $function, object self, object text) 
{ 
... 
} 

Closure ve PythonFunction Microsoft.Scripting.dll gelen IronPython sınıfları (ve IronPython.dll). Şimdiye kadar çok iyi. Bu yöntem C# koduyla çağrılabilir mi? Metodun parametrelerini ayarlaması nedeniyle gibi yansımayı kullanma düşüncesi daha zor gözükmektedir. Doğru şekilde başlatılmışlarsa, yöntemin sorunsuz çalışmasını bekleyebilir miyiz?

Bu yöntemleri C# olarak adlandırmanın daha iyi bir yolu var mı? Çeşitli farklı nedenlerle, betiğin bir .NET derlemesi olarak oluşturulmasını ve komut dosyasının kendisini çağırmamasını tercih ediyoruz.

cevap

8

Sıralama. Python yöntemlerine doğrudan C# kodundan erişemezsiniz. C# 4.0 ve dinamik anahtar kelimeyle oynamadığınız sürece veya çok özel iseniz;). Ancak, bir IronPython sınıfını bir DLL'ye derleyebilir ve sonra da bu yöntemlere erişmek için IronPython'u C# kullanarak kullanabilirsiniz (bu IronPython 2.6 ve .NET 2.0 içindir).

class MyClass: 
    def __init__(self): 
     print "I'm in a compiled class (I hope)" 

    def somemethod(self): 
     print "in some method" 

    def isodd(self, n): 
     return 1 == n % 2 

bunu derleme (I SharpDevelop kullanıyoruz) clr.CompileModules yöntem de çalışması gerekir:

using System; 
using System.IO; 
using System.Reflection; 
using IronPython.Hosting; 
using Microsoft.Scripting.Hosting; 
// we get access to Action and Func on .Net 2.0 through Microsoft.Scripting.Utils 
using Microsoft.Scripting.Utils; 


namespace TestCallIronPython 
{ 
    class Program 
    { 
     public static void Main(string[] args) 
     { 
      Console.WriteLine("Hello World!"); 
      ScriptEngine pyEngine = Python.CreateEngine(); 

      Assembly myclass = Assembly.LoadFile(Path.GetFullPath("MyClass.dll")); 
      pyEngine.Runtime.LoadAssembly(myclass); 
      ScriptScope pyScope = pyEngine.Runtime.ImportModule("MyClass"); 

      // Get the Python Class 
      object MyClass = pyEngine.Operations.Invoke(pyScope.GetVariable("MyClass")); 

      // Invoke a method of the class 
      pyEngine.Operations.InvokeMember(MyClass, "somemethod", new object[0]); 

      // create a callable function to 'somemethod' 
      Action SomeMethod2 = pyEngine.Operations.GetMember<Action>(MyClass, "somemethod"); 
      SomeMethod2(); 

      // create a callable function to 'isodd' 
      Func<int, bool> IsOdd = pyEngine.Operations.GetMember<Func<int, bool>>(MyClass, "isodd"); 
      Console.WriteLine(IsOdd(1).ToString()); 
      Console.WriteLine(IsOdd(2).ToString()); 

      Console.Write("Press any key to continue . . . "); 
      Console.ReadKey(true); 
     } 
    } 
} 

önemsiz bir Python sınıfı böyle yapın:

Böyle bir C# program oluşturun. Sonra derlenmiş MyClass.dll'u derlenmiş C# programının yaşadığı ve çalıştırdığı dizine koyun.

Hello World! 
I'm in a compiled class (I hope) 
in some method 
in some method 
True 
False 
Press any key to continue . . . 

Bu aynı zamanda oluşturmak ve küçük Python 'saplama' derlemek zorunda ve ortadan kaldırır Jeff'in daha doğrudan bir çözüm içeriyor içeri yöntemlerine erişmek C# işlev çağrıları nasıl yaratılacağı gösterilmektedir: Sen sonucunda bu almalısınız Python sınıfı.

+0

Jeff Hardy'nin yanıtı, bir ScriptEngine'den derlenmiş dll/python sınıfını kullanmanın daha doğrudan bir yolu olup olmadığımı merak etmemi sağlıyor… – djlawler

+0

Kodu biraz kolaylaştırdım ve bir python yöntemine çağrı ekledim. Ayrıca, bunu (bu yardımcı olabilir) buldum: http://codingbox.blogspot.com/2009_11_01_archive.html – djlawler

+0

Bunu yapmak için daha doğrudan bir yol için http://pastie.org/797185 göz atın. –

6

clr.CompileModules yalnızca bir yükleme süresi en iyi duruma getirme - komut dosyalarını doğrudan C# gibi statik bir dize için kullanılabilir yapmaz. IronPython çalışma zamanını barındırmanız gerekir ve daha sonra DLL'yi çalışma zamanına yükleyebilir ve buna erişmek için IronPython'un barındırma arayüzlerini kullanabilirsiniz.

+0

Teşekkürler. DLL'e erişmek için IronPython'un barındırma arabirimlerini kullanmanın bir örneğiyle yardımcı olabilir misiniz? – Alex

+0

@Alex: Djlawler'in yanıtına ve yorumuma bakın. –

İlgili konular