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)
但是我认为这样做没有太大优势,除非您需要例如在使用任何值之前预先检查所有值。