Python — Получение переменных с помощью vbscript

#python #vbscript

Вопрос:

Я работаю над кодом python, который вызывает скрипт VB, предназначенный для выполнения некоторых вычислений. Эти вычисления ДОЛЖНЫ выполняться в скрипте VB, и нет никакого способа перенести их в скрипт Python.

Я отправляю переменные в скрипте VB следующим образом:

 WScript.Echo("TEST")
 

И попробуйте получить их в коде Python как:

 p = subprocess.Popen(['cscript.exe', VB_path, nLM, nSD, nSO, nTWS, nROH, 
                      nMOH1, nMOH2, nRad1, nRad3, nLstk, nT_Shaft_EN, S_path, 
                      S_file, S_version, nkE_ref, nTC_ref, nNImax, nCost_PM, 
                      nCost_Steel, nCost_Wire, '//nologo'], stdout=subprocess.PIPE, shell=True)
out, err = p.communicate()
out
 

Результат, который я получаю для «выхода», следующий:

 b'Testrn'
 

Мой вопрос: как я могу отправить несколько выходных данных с простой переменной ? Кроме того, в качестве бонусного вопроса, есть ли какой-либо очевидный способ отправить массив таким способом из vb в скрипт python ?

Ответ №1:

Поскольку текст (через поток stdout) является вашим методом связи, очевидным способом отправки нескольких значений (структуры данных) является их сериализация в хорошо известном формате, о котором могут договориться оба партнера по общению.

Распространенным способом сделать это был бы JSON, но JSON сравнительно сложно создать с помощью vanilla VBScript. Другими очевидными кандидатами были бы CSV, XML или INI, но в конечном счете: любой формат, который вы можете придумать.

Преимущество выбора хорошо известных форматов заключается в том, что кто-то другой уже написал для них синтаксический анализатор. Форматы, которые вы придумываете, требуют, чтобы вы сами написали синтаксический анализатор.

Давайте предположим, что формат INI способен представлять ваши данные:

 [section]
key_a = value_a
key_b = value_b
 

Такой вывод легко генерировать в VBScript, и у Python есть конфигурационный анализатор для его чтения.

Так что мы могли бы написать пару помощников в VBScript:

 Sub OutputSection(name)
    WScript.StdOut.WriteLine(vbNewLine amp; "[" amp; name amp; "]")
End Sub

Sub OutputVariable(name, value)
    Dim i
    If IsArray(value) Then
        If UBound(value) = -1 Then
            WScript.StdOut.WriteLine(name amp; ". = ")    ' to signify empty array
        Else
            For i = 0 To UBound(value) - 1
                OutputVariable(name amp; "." amp; i, value(i))
            Next
        End If
    Else
        WScript.StdOut.WriteLine(name amp; " = " amp; value)
    End IF
End Sub
 

Вызов их в вашем сценарии приведет к аккуратно организованному выходу

 [main]
key = value

[some_array]
array.0 = value0
array.1 = value1
array.2 = value2
 

В Python вы можете добавить шаг постобработки, который превращает отдельные элементы массива в списки.

Или вы используете Join() в VBScript для массивов, что упростит как Sub OutputVariable() синтаксический анализ, так и синтаксический анализ на Python, но вы рискуете исказить свои данные, если разделитель списка может встречаться в значении массива. Это компромисс.