Я читал подобные вопросы, касающиеся передачи текста JSON в качестве аргумента командной строки с помощью Python, но ни одно из решений не помогло в моем случае.
Я автоматизирую сценарий Python, и автоматизация запускает сценарий PowerShell, который принимает объект JSON, сгенерированный из потока автоматизации Power. Все работает отлично, пока не доходит до обработки JSON в моем скрипте Python.
Моя цель — преобразовать JSON в словарь, чтобы я мог использовать пары «ключ-значение» в своем коде.
Мой сценарий PowerShell выглядит так:
Python script.py {"Items":[{"Name":"foo","File":"\\\\files\\foo\\foo.csv"},{"Name":"bar","File":"\\\\files\\bar\\bar.csv"},{"Name":"baz","File":"\\\\files\\baz\\baz.csv"}]}
Мой JSON выглядит так:
{
"Items": [
{
"Name": "foo",
"File": "\\\\files\\foo\\foo.csv"
},
{
"Name": "bar",
"File": "\\\\files\\bar\\bar.csv"
},
{
"Name": "baz",
"File": "\\\\files\\baz\\baz.csv"
}
]
}
Я попробовал это решение от SO:
if len(sys.argv) > 1:
d = json.loads(sys.argv[1])
print(d)
но он возвращает эту ошибку:
Unexpected token ':' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
Я не знаю, как решить эту проблему, любые предложения помогут!
Вы показываете нам код Python. Вы показываете JSON, который собираетесь передать ему. Вы не показываете нам, как вы помещаете JSON в командную строку, поэтому сейчас мы понятия не имеем, действительно ли вы это делаете правильно.
Это не похоже на сообщение об ошибке Python, я предполагаю, что это ошибка PowerShell. Итак, проблема в том, как вы помещаете JSON в командную строку PowerShell.
Это особенно актуально, поскольку FullyQualifiedErrorId не является ошибкой Python — для меня это больше похоже на ошибку PowerShell.
@CharlesDuffy Я обновил вопрос с помощью PowerShell
Я не думал об этом вчера, но думаю, что есть гораздо лучший способ справиться с этим, не требующий побега. Смотрите обновление в моем ответе.






В зависимости от используемой вами версии PowerShell вам придется обрабатывать ее по-разному. Если вы используете pwsh 7.3+, решение так же просто, как заключить строку Json в одинарные кавычки. В противном случае, если вы используете это ниже, вам придется экранировать двойные кавычки с помощью \, иначе они будут съедены при передаче через ваш скрипт Python.
Используя это, можно обрабатывать это динамически:
$json = @'
{
"Items": [
{
"Name": "foo",
"File": "\\\\files\\foo\\foo.csv"
},
{
"Name": "bar",
"File": "\\\\files\\bar\\bar.csv"
},
{
"Name": "baz",
"File": "\\\\files\\baz\\baz.csv"
}
]
}
'@
if ($PSVersionTable.PSVersion -ge '7.3') {
Python script.py $json
}
else {
Python script.py $json.Replace('"', '\"')
}
Тогда предположим, что ваш код Python будет:
import json
import sys
if len(sys.argv) > 1:
d = json.loads(sys.argv[1])
for i in d['Items']:
print(i)
Тогда вывод в вашей консоли PowerShell будет:
{'Name': 'foo', 'File': '\\\\files\\foo\\foo.csv'}
{'Name': 'bar', 'File': '\\\\files\\bar\\bar.csv'}
{'Name': 'baz', 'File': '\\\\files\\baz\\baz.csv'}
Более простой и, вероятно, более надежной альтернативой, которая не требует экранирования кавычек в любой версии PowerShell, может быть преобразование строки Json в Base64 в PowerShell и передача ее в качестве аргумента в ваш скрипт Python:
# Json defined here
$json = @'
...
...
'@
$b64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($json))
Python script.py $b64
Тогда в Python код работает с минимальными изменениями:
from base64 import b64decode
import json
import sys
if len(sys.argv) > 1:
d = json.loads(b64decode(sys.argv[1]))
for i in d['Items']:
print(i)
В этой ситуации вы можете либо передать словарь в виде строки:
python script.py '{"Items":[{"Name":"foo","File":"\\\\files\\foo\\foo.csv"},{"Name":"bar","File":"\\\\files\\bar\\bar.csv"},{"Name":"baz","File":"\\\\files\\baz\\baz.csv"}]}'
или передайте файл, содержащий json, и прочитайте этот файл в Python:
python script.py test.json
где test.json — ваш json. Соответствующий код Python будет выглядеть примерно так:
def main():
file_path = sys.argv[1]
with open(file_path, 'r') as file:
d = json.load(file)
print(d)
if __name__ == "__main__":
main()
Как вы вызываете свой скрипт Python (т.е. передаете ему данные JSON)? почему бы не сбросить JSON в файл (из потока автоматизации), а затем просто указать имя файла в качестве параметра в скрипте Python? Вы уверены, что ошибка исходит от Python?