简体   繁体   English

使用IronPython中的可变参数调用CLR方法

[英]calling CLR method with variable arguments from IronPython

I am using Iron Python as an added 'for free' tool to test the an API that wrapps comms to some custom hardware so the non-development team can play with the hardware via python. 我正在使用Iron Python作为一个额外的“免费”工具来测试一个API,它将comms包装到一些自定义硬件中,因此非开发团队可以通过python使用硬件。

However I can't work out how to get .NET void func(params object[] args) to map to Python def (*args) . 但是我无法弄清楚如何将.NET void func(params object[] args)映射到Python def (*args)

Here is some code to explain. 这里有一些代码可以解释。

I have a type that allows injecting a logging callback to format and deal with messages is follows the signature of Console.WriteLine and Debug.WriteLine. 我有一个允许注入日志回调格式和处理消息的类型遵循Console.WriteLine和Debug.WriteLine的签名。

public class Engine
{
    Action<string, object[]> _logger;
    public void Run()
    {
        Log("Hello '{0}'", "world");
    }
    public void SetLog(Action<string, object[]> logger)
    {
        _logger = logger;
    }
    void Log(string msg, params object[] args)
    {
        _logger(msg, args);
    }
}

in my IronPython code 在我的IronPython代码中

import clr
from System import *
from System.IO import Path
clr.AddReferenceToFileAndPath(Path.GetFullPath(r"MyAssembly.dll"))
from MyNamespace import *

def logger(msg, *args):
    print( String.Format(msg, args))
    print( String.Format(msg, list(args)))
    print( String.Format(msg, [args]))
    a=[]
    for i in args:
        a.append(i)
    print( String.Format(msg, a) )

e = Engine()
e.SetLog(logger)
e.Run()

output 产量

Hello '('world',)'
Hello 'IronPython.Runtime.List'
Hello 'IronPython.Runtime.List'
Hello 'IronPython.Runtime.List'

I would like 我想要

Hello 'world'

Because String.Format handles your iron python objects (tuple for your first output case, lists for the last three) as single objects and is not aware that you would like the python collection to be used as params object[] you are getting the unexpected output. 因为String.Format处理你的铁python对象(你的第一个输出案例的元组,最后三个列表)作为单个对象,并且不知道你希望python集合被用作params object[]你得到意外输出。 The single python object/tuple is implicitly created when def logger is invoked. 调用def logger时会隐式创建单个python对象/元组。

Depending on your actual use-case/style you can solve this in different ways. 根据您的实际用例/风格,您可以通过不同方式解决此问题。

The most python-y way would be expanding the arguments at their call site like Jeff explains in his answer: 杰夫在他的回答中解释说,最蟒蛇的方式是在他们的呼叫网站上扩展争论:

def logger(msg, *args):
    print( String.Format(msg, *args) )

If you call logger only as from CLR as implementation of Action<string, object[]> you could just have args be a single (not variable) argument of type object[] like 如果仅从CLR调用logger作为Action<string, object[]>你可以让args成为object[]类型的单个(非变量)参数

def logger(msg, args):
    print( String.Format(msg, args) )

If you would like to call logger from python with variable arguments as well (and you don't mind the back and forth conversion) you could do 如果你想用python调用带有可变参数的logger (并且你不介意来回转换)你可以做

def logger(msg, *args):
    print( String.Format(msg, Array[object](args)) )

Unless I'm misunderstanding your question, this should work: 除非我误解你的问题,否则这应该有效:

def logger(msg, *args):
    print(String.Format(msg, *args))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM