PythonNet не документирует это так же четко, как IronPython, но делает почти то же самое.
Итак, давайте посмотрим на документацию IronPython для ref
and out
parameters:
The Python language passes all arguments by-value. There is no syntax to indicate that an argument should be passed by-reference like there is in .NET languages like C# and VB.NET via the ref and out keywords. IronPython supports two ways of passing ref or out arguments to a method, an implicit way and an explicit way.
In the implicit way, an argument is passed normally to the method call, and its (potentially) updated value is returned from the method call along with the normal return value (if any). This composes well with the Python feature of multiple return values…
In the explicit way, you can pass an instance of clr.Reference[T]
for the ref or out argument, and its Value field will get set by the call. The explicit way is useful if there are multiple overloads with ref parameters…
Есть примеры для обоих. Но адаптировать его к вашему конкретному случаю:
itemIDs, itemNames = GetItems()
Или, если вы действительно хотите:
itemIDsRef = clr.Reference[Array[int]]()
itemNamesRef = clr.Reference[Array[String]]()
GetItems(itemIDs, itemNames)
itemIDs, itemNames = itemIDsRef.Value, itemNamesRef.Value
CPython с использованием PythonNet делает в основном то же самое. Простой способ сделать параметры out
- это не передавать их и принимать их как дополнительные возвращаемые значения, а для параметров ref
передавать входные значения в качестве аргументов и принимать выходные значения в качестве дополнительных возвращаемых значений. Также как неявное решение IronPython. (За исключением того, что функция void
с параметрами ref
или out
всегда возвращает None
до аргументов ref
или out
, даже если это не будет в IronPython.) Вы можете легко понять это, проверив возвращаемые значения. Таким образом, в вашем случае:
_, itemIDs, itemNames = GetItems()
Между тем, тот факт, что это происходит, чтобы быть массивы не делает вещи тяжелее. Как объясняет the docs, PythonNet предоставляет итерируемый интерфейс для всех коллекций IEnumerable
, а также протокол последовательности для Array
. Таким образом, вы можете сделать это:
И Int32
и String
объекты будут преобразованы в родной int
/long
и str
/unicode
объекты так же, как если бы они были возвращены непосредственно.
Если вы действительно хотите явно преобразовать их в собственные значения, вы можете. map
или понимание списка даст вам список Python из любого итеративного файла, включая обертку PythonNet вокруг Array
или других IEnumerable
.И вы можете явно сделать long
или unicode
из Int32
или String
, если вам нужно. Итак:
itemIDs = map(int, itemIDs)
itemNames = map(unicode, itemNames)
Но я не вижу много преимуществ, чтобы сделать это, если не нужно, например, предварительно проверить все значения, прежде чем использовать любой из них.
Почему вы хотите преобразовать их обратно в типы Python, а не просто использовать их? – abarnert
@abarnet Так как вы сделали такую отличную работу в своем ответе ниже, я собираюсь прокомментировать там. – Jonno