Как вызвать пространство имен C # / .NET в IronPython? - PullRequest
1 голос
/ 11 октября 2011

Я пытаюсь повторить следующее в IronPython, и поиск пока бесполезен и / или разочаровывает.

namespace Groceries
{
     public class ChocolateMilk : Milk
     {
          // Other stuff here
     }
}

Идея состоит в том, что скомпилированная библиотека Python DLL будет загружена в программу на C #через System.Reflection.Assembly.Load и GetType ("Groceries.ChocolateMilk") в загруженной DLL не вернет ноль.

Самый последний ответ, который мне удалось найти, был в 2008 году и сказал, что это былневозможно без использования Hosting API - http://lists.ironpython.com/pipermail/users-ironpython.com/2008-October/008684.html.

Буду очень признателен за любые предложения о том, как этого добиться.Любые выводы, что в настоящее время это невозможно сделать с помощью IronPython, также будут оценены, но в меньшей степени.

1 Ответ

4 голосов
/ 12 октября 2011

Я немного запутался в том, что вы спрашиваете здесь.Вы пытаетесь создать экземпляр этого кода C # в своих модулях IronPython?Или у вас есть эквивалентные классы, написанные на IronPython, и вы хотите создать их экземпляр в своем коде C #?

Исходя из ссылки, которую вы разместили, я полагаю, вы переходите на последнюю и имеете классы IronPython, которые вы хотитесоздан в вашем коде C #.Ответ в том, что вы не можете напрямую их создать.Когда вы компилируете код IronPython в сборку, вы не можете использовать типы, определенные там, с вашим обычным кодом .NET, так как между классами IronPython и классами .NET нет однозначного отображения.Вам нужно будет разместить сборку в вашем проекте C # и создать его таким образом.

Рассмотрим этот модуль, Groceries.py скомпилированный в Groceries.dll, находящийся в рабочем каталоге:

class Milk(object):
    def __repr__(self):
        return 'Milk()'

class ChocolateMilk(Milk):
    def __repr__(self):
        return 'ChocolateMilk()'

Чтобы разместить модуль в своем коде C #:

using System;

using IronPython.Hosting;
using System.IO;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        var engine = Python.CreateEngine();
        var groceriesPath = Path.GetFullPath(@"Groceries.dll");
        var groceriesAsm = Assembly.LoadFile(groceriesPath);
        engine.Runtime.LoadAssembly(groceriesAsm);

        dynamic groceries = engine.ImportModule("Groceries");
        dynamic milk = groceries.ChocolateMilk();
        Console.WriteLine(milk.__repr__()); // "ChocolateMilk()"
    }
}

В противном случае вы можете пойти другим путем и создать экземпляр вашего типа .NET в вашем коде IronPython (как подсказывает ваш заголовок).Вам нужно будет добавить путь к вашей сборке, сослаться на него, а затем создать его по мере необходимости.

# add to path
import sys
sys.path.append(r'C:\path\to\assembly\dir')

# reference the assembly
import clr
clr.AddReferenceToFile(r'Groceries.dll')

from Groceries import *
chocolate = ChocolateMilk()
print(chocolate)
...