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

发布于 2021-01-29 17:01:02

我正在尝试在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类型?

关注者
0
被浏览
51
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    PythonNet并没有像IronPython那样清楚地记录这件事,但是它几乎做同样的事情。

    因此,让我们看一下IronPython文档中的refout参数

    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带有reforout参数的函数总是Nonereforout参数之前返回,即使它不在IronPython中也是如此。)您可以通过检查返回值来很容易地找出它。因此,在您的情况下:

    _, itemIDs, itemNames = GetItems()
    

    同时,这些恰好是数组的事实并没有使事情变得更难。正如文档所解释的那样,PythonNet为所有IEnumerable集合提供了可迭代的接口,并为提供了序列协议Array。因此,您可以执行以下操作:

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

    Int32String对象将转换为本地int/longstr/unicode对象,就好像它们直接返回。


    如果您确实想将这些值显式转换为本机值,则可以。map或列表理解将为您提供任何可迭代的Python列表,包括围绕Array或的PythonNet包装器IEnumerable。你可以明确地使一个longunicode出去的Int32或者String如果您需要。所以:

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

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



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看