PythonNet 没有像 IronPython 那样清楚地记录这一点,但它几乎做了同样的事情。
因此,让我们看一下 IronPython 文档ref
和out
参数:
Python 语言按值传递所有参数。没有语法表明参数应该通过引用传递,就像在 .NET 语言(如 C# 和 VB.NET)中通过 ref 和 out 关键字。IronPython 支持将 ref 或 out 参数传递给方法的两种方式,隐式方式和显式方式。
在隐式方式中,参数通常被传递给方法调用,并且其(可能)更新的值与正常的返回值(如果有)一起从方法调用返回。这与 Python 的多返回值特性很好地组合在一起……</p>
以显式方式,您可以为 ref 或 out 参数传递一个实例clr.Reference[T]
,其 Value 字段将由调用设置。如果有多个带有 ref 参数的重载,则显式方法很有用……</p>
两者都有例子。但要根据您的具体情况定制它:
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
参数的函数总是在or参数None
之前返回,即使它不会在 IronPython 中。)您可以通过检查返回值很容易地找出它。所以,在你的情况下:ref
out
_, itemIDs, itemNames = GetItems()
同时,这些恰好是数组的事实并没有使事情变得更难。正如文档解释的那样,PythonNet 为所有IEnumerable
集合提供了可迭代接口,并为Array
. 所以,你可以这样做:
for itemID, itemName in zip(itemIDs, itemNames):
print itemID, itemName
并且Int32
andString
对象将被转换为原生的int
/long
和str
/unicode
对象,就像它们被直接返回一样。
如果您真的想将这些显式转换为本机值,您可以。map
或者列表推导式将为您提供来自任何可迭代的 Python 列表,包括围绕 anArray
或 other的 PythonNet 包装器IEnumerable
。如果需要,您可以明确地制作 along
或unicode
out 。所以:Int32
String
itemIDs = map(int, itemIDs)
itemNames = map(unicode, itemNames)
但我认为这样做并没有多大优势,除非您需要,例如,在使用任何值之前预先检查所有值。