如何使用在Python中修改的.NET方法?

Jon*_*nno 5 .net python pass-by-reference python.net

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

public void GetItems(
out int[] itemIDs,
out string[] itemNames
)
Run Code Online (Sandbox Code Playgroud)

如何使用Python for .NET模块在Python中使用此方法?

编辑:忘记提到这是在CPython而不是IronPython.

附加信息.当我执行以下操作时:

itemIDs = []
itemNames = []
GetItems(itemIDs, itemNames)
Run Code Online (Sandbox Code Playgroud)

我得到一个输出:

(None, <System.Int32[] at 0x43466c0>, <System.String[] at 0x43461c0>)
Run Code Online (Sandbox Code Playgroud)

我只需要弄清楚如何将这些转换回python类型?

aba*_*ert 7

PythonNet并没有像IronPython那样清楚地记录这一点,但它几乎完全相同.

那么,让我们看一下IronPython文档refout参数:

Python语言按值传递所有参数.没有语法表明参数应该通过引用传递,就像通过ref和out关键字在.NET语言(如C#和VB.NET)中一样.IronPython支持两种将ref或out参数传递给方法的方法,一种隐式方式和一种显式方式.

以隐式方式,参数通常传递给方法调用,并且从方法调用返回其(可能)更新的值以及正常返回值(如果有的话).这很好地与多个返回值的Python功能组合在一起......

以显式方式,您可以传递clr.Reference[T]ref或out参数的实例,并且其Value字段将由调用设置.如果有多个带参数的重载,那么显式方法很有用......

两者都有例子.但要根据您的具体情况量身定制:

itemIDs, itemNames = GetItems()
Run Code Online (Sandbox Code Playgroud)

或者,如果你真的想要:

itemIDsRef = clr.Reference[Array[int]]()
itemNamesRef = clr.Reference[Array[String]]()
GetItems(itemIDs, itemNames)
itemIDs, itemNames = itemIDsRef.Value, itemNamesRef.Value
Run Code Online (Sandbox Code Playgroud)

使用PythonNet的 CPython 基本上做同样的事情.执行out参数的简单方法是不传递它们并将它们作为额外的返回值接受,以及ref将输入值作为参数传递并将输出值作为额外返回值接受的参数.就像IronPython的隐式解决方案一样.(除非void带有refout参数的函数总是Nonerefout参数之前返回,即使它不在IronPython中.)你可以通过检查返回值很容易地弄清楚它.所以,在你的情况下:

_, itemIDs, itemNames = GetItems()
Run Code Online (Sandbox Code Playgroud)

与此同时,这些恰好是阵列的事实并没有让事情变得更难.正如文档所解释的那样,PythonNet为所有IEnumerable集合提供了可迭代的接口,并为其提供了序列协议Array.所以,你可以这样做:

for itemID, itemName in zip(itemIDs, itemNames):
    print itemID, itemName
Run Code Online (Sandbox Code Playgroud)

Int32String对象将转换为本地int/ longstr/ unicode就像他们直接返回的对象.


如果您真的想要将这些显式转换为本机值,则可以.map或者列表推导将为您提供任何可迭代的Python列表,包括围绕一个Array或其他的PythonNet包装器IEnumerable.你可以明确地制作一个long或者unicode一个Int32或者String如果你需要的话.所以:

itemIDs = map(int, itemIDs)
itemNames = map(unicode, itemNames)
Run Code Online (Sandbox Code Playgroud)

但是我没有看到这样做的好处,除非您需要在使用任何值之前预先检查所有值.

  • 谢谢,不幸的是我忘了提到我使用CPython而不是IronPython. (2认同)