如何使用在Python中进行修改的.NET方法?
我正在尝试在Python中使用.NETdll。在.NET语言中,该方法要求通过引用将其传递给2个数组,然后对其进行修改:
public void GetItems(
out int[] itemIDs,
out string[] itemNames
)
如何使用Python for .NET模块在Python中使用此方法?
编辑:忘记提及这是在CPython中而不是IronPython。
附加信息。当我执行以下操作时:
itemIDs = []
itemNames = []
GetItems(itemIDs, itemNames)
我得到这样的输出:
(None, <System.Int32[] at 0x43466c0>, <System.String[] at 0x43461c0>)
我是否只需要弄清楚如何将它们转换回python类型?
-
PythonNet并没有像IronPython那样清楚地记录这件事,但是它几乎做同样的事情。
因此,让我们看一下IronPython文档中的
ref
和out
参数:Python语言按值传递所有参数。没有语法表明应该像通过C#和VB.NET的.NET语言一样通过ref和out关键字按引用传递参数。IronPython支持两种将ref或out参数传递给方法的方式,即隐式方式和显式方式。
以隐式方式,参数通常传递给方法调用,并且其(潜在地)更新的值与常规返回值(如果有)一起从方法调用中返回。这与多个返回值的Python功能很好地结合在一起…
以显式的方式,您可以传递
clr.Reference[T]
ref或out参数的实例,并且其Value字段将由调用设置。如果引用参数有多个重载,则显式方法很有用……两者都有例子。但是要针对您的特定情况进行调整:
itemIDs, itemNames = GetItems()
或者,如果您确实想要:
itemIDsRef = clr.Reference[Array[int]]() itemNamesRef = clr.Reference[Array[String]]() GetItems(itemIDs, itemNames) itemIDs, itemNames = itemIDsRef.Value, itemNamesRef.Value
使用PythonNet的CPython基本上具有相同的作用。做
out
参数的简单方法是不传递它们并将其接受为额外的返回值,ref
而使参数传递输入值作为参数并接受输出值作为额外的返回值。就像IronPython的隐式解决方案一样。(除了void
带有ref
orout
参数的函数总是None
在ref
orout
参数之前返回,即使它不在IronPython中也是如此。)您可以通过检查返回值来很容易地找出它。因此,在您的情况下:_, itemIDs, itemNames = GetItems()
同时,这些恰好是数组的事实并没有使事情变得更难。正如文档所解释的那样,PythonNet为所有
IEnumerable
集合提供了可迭代的接口,并为提供了序列协议Array
。因此,您可以执行以下操作:for itemID, itemName in zip(itemIDs, itemNames): print itemID, itemName
而
Int32
和String
对象将转换为本地int
/long
和str
/unicode
对象,就好像它们直接返回。
如果您确实想将这些值显式转换为本机值,则可以。
map
或列表理解将为您提供任何可迭代的Python列表,包括围绕Array
或的PythonNet包装器IEnumerable
。你可以明确地使一个long
或unicode
出去的Int32
或者String
如果您需要。所以:itemIDs = map(int, itemIDs) itemNames = map(unicode, itemNames)
但是我认为这样做没有太大优势,除非您需要例如在使用任何值之前预先检查所有值。