如何使用它修改的地方Python中的.NET方法?地方、方法、使用它、Python

2023-09-03 17:39:49 作者:呸!

我想使用Python中的.NET的DLL。在.NET语言的方法需要通过引用它,然后修改它传递2个数组:

I am trying to use a .NET dll in Python. In a .NET language the method requires passing it 2 arrays by reference which it then modifies:

public void GetItems(
out int[] itemIDs,
out string[] itemNames
)

我怎么可以用这种方法在Python使用Python为.NET模块?

How can I use this method in Python using the Python for .NET module?

编辑:忘记提到这是CPython的不是IronPython的

Forgot to mention this is in CPython not IronPython.

附加信息。 当我做了以下内容:

Additional info. When I do the following:

itemIDs = []
itemNames = []
GetItems(itemIDs, itemNames)

我得到这样的输出:

I get an output like:

(None, <System.Int32[] at 0x43466c0>, <System.String[] at 0x43461c0>)

我只需要弄清楚如何回将它们转换为Python类型?

Do I just need to figure out how to convert these back into python types?

推荐答案

PythonNet不包含本很清楚表达的IronPython的,但它几乎同样的事情。

PythonNet doesn't document this quite as clearly as IronPython, but it does almost the same thing.

那么,让我们来看看IronPython的文档 REF 退出参数:

So, let's look at the IronPython documentation for ref and out parameters:

Python语言的推移,值的所有参数。有没有语法来表示一个参数应该按引用传递像有.NET语言,如C#和VB.NET通过ref和out关键字。 IronPython的支持传递ref或out参数的方法,一种含蓄的方式和明确的方式有两种方式。

The Python language passes all arguments by-value. There is no syntax to indicate that an argument should be passed by-reference like there is in .NET languages like C# and VB.NET via the ref and out keywords. IronPython supports two ways of passing ref or out arguments to a method, an implicit way and an explicit way.

在隐式方式,一种说法通常传递到方法调用,并且它的(可能)更新值从呼叫沿与正常返回值(如果有的话)方法返回。这与多个返回值的Python的功能组成以及...

In the implicit way, an argument is passed normally to the method call, and its (potentially) updated value is returned from the method call along with the normal return value (if any). This composes well with the Python feature of multiple return values…

在明确的方式,你可以通过 clr.Reference的一个实例[T] 的ref或out参数,它的值字段将获得由呼叫建立。如果有多个重载与ref参数显式的方法是有用...

In the explicit way, you can pass an instance of clr.Reference[T] for the ref or out argument, and its Value field will get set by the call. The explicit way is useful if there are multiple overloads with ref parameters…

有例子为。但把它定制您的具体情况:

There are examples for both. But to tailor it to your specific case:

itemIDs, itemNames = GetItems()

或者,如果你真的想要的:

Or, if you really want:

itemIDsRef = clr.Reference[Array[int]]()
itemNamesRef = clr.Reference[Array[String]]()
GetItems(itemIDs, itemNames)
itemIDs, itemNames = itemIDsRef.Value, itemNamesRef.Value

CPython的使用 PythonNet 做基本上是同样的事情。最简单的方法来做到退出参数是无法通过他们,接受他们成为多余的返回值,以及 REF 参数通过输入值作为参数,并接受输出值作为额外的返回值。就像IronPython的的隐式的解决方案。 (除与 REF 退出参数无效功能总是返回 REF之前退出参数,甚至如果它不会在IronPython的。)您可以通过检查返回值很容易弄清楚pretty的。所以,你的情况:

CPython using PythonNet does basically the same thing. The easy way to do out parameters is to not pass them and accept them as extra return values, and for ref parameters to pass the input values as arguments and accept the output values as extra return values. Just like IronPython's implicit solution. (Except that a void function with ref or out parameters always returns None before the ref or out arguments, even if it wouldn't in IronPython.) You can figure it out pretty easily by inspecting the return values. So, in your case:

_, itemIDs, itemNames = GetItems()

同时,事实上这些恰好是阵列不使事情任何更难。由于的文档解释,PythonNet提供了可迭代接口,所有的的IEnumerable 的集合,而序列的协议,以及为阵列。所以,你可以这样做:

Meanwhile, the fact that these happen to be arrays doesn't make things any harder. As the docs explain, PythonNet provides the iterable interface for all IEnumerable collections, and the sequence protocol as well for Array. So, you can do this:

for itemID, itemName in zip(itemIDs, itemNames):
    print itemID, itemName

的Int32 字符串对象将转换为本地 INT / STR / UNI code 对象,就好像他们是直接返回。

And the Int32 and String objects will be converted to native int/long and str/unicode objects just as if they were returned directly.

如果你真的想明确地将这些原生值,就可以了。 地图或列表COM prehension会给你一个Python列表,可迭代的,包括周围的 A PythonNet封装阵列或其他的IEnumerable 。你可以明确地做一个 UNI code 出的的Int32 字符串如果您需要。所以:

If you really want to explicitly convert these to native values, you can. map or a list comprehension will give you a Python list from any iterable, including a PythonNet wrapper around an Array or other IEnumerable. And you can explicitly make a long or unicode out of an Int32 or String if you need to. So:

itemIDs = map(int, itemIDs)
itemNames = map(unicode, itemNames)

不过,我看不出有多大的优势,这样做,除非你需要,例如,$ P $使用其中的任何之前对检查所有的值。

But I don't see much advantage to doing this, unless you need to, e.g., pre-check all the values before using any of them.