Как передать аргумент *args в функцию Python в виде строки

Я использую pytubefix для создания загрузчика Youtube.

API позволяет мне писать такой код:

YouTube(url).streams.filter(progressive=True)

Но предположим, что у меня есть строка, хранящаяся в переменной типа

args = "progressive=True"

Как я могу использовать строку args для вызова функции, как если бы я напрямую указал те же аргументы ключевого слова?

Если я попробую

YouTube(url).streams.filter(args)

это не делает то, что я хочу.

Почему у вас это вообще строка?

deceze 05.08.2024 10:35

Обычно вы передаете диктат как кварги: stackoverflow.com/questions/5710391/…

Maurice Meyer 05.08.2024 10:36

Я предполагаю, что ваш загрузчик имеет интерфейс командной строки — иначе откуда взялся url? Это предполагает, что переменная args также поступает из командной строки или, возможно, из файла конфигурации. В любом случае вам необходимо использовать специальный синтаксический анализатор (например, argparse , configparser , json и т. д.) для преобразования входных данных в форму, которую можно передавать в качестве аргументов функции.

ekhumoro 05.08.2024 13:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
8
3
73
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не можете передавать аргументы ключевого слова в виде строк.

Что вы можете сделать, так это разобрать его самостоятельно в подходящую структуру.

import re
kwargs = {x[0]: x[1] for x in re.findall(r"([^;=]+)=([^;=]+)", args)}
YouTube(url).streams.filter(**kwargs)

Я произвольно добавил ; в качестве разделителя, чтобы вы могли сказать args = "foo=bar;baz=quux"

Это просто предполагает, что все значения являются строками. Если вам нужно проанализировать, например. "False" в правильное логическое значение False или поддерживать числа int или float, очевидно, добавьте для этого необходимую логику.

В этом случае это будет передано True как строка, что, вероятно, потерпит неудачу. Чтобы правильно справиться с этим, вам понадобится больше кода, который будет становиться все более громоздким и плохо определенным. Просто не играть – единственный правильный ответ здесь.

deceze 05.08.2024 10:42
"True" — это «правда», поэтому это действительно может сработать. Это не будет работать для аргументов ключевых слов, которые должны быть числами, или "False" vs False Обновлено, чтобы отметить это в самом ответе.
tripleee 05.08.2024 11:27

Вы можете просто разделить строку аргумента на «=", чтобы разделить два компонента. Однако в вашем примере простое разделение даст вам две строки, но вам нужно логическое значение, поэтому...

def myfunc(*, progressive):
    print(progressive)

args = "progressive=True"
k, v = args.split(" = ")
myfunc(**{k:v= = "True"})
Ответ принят как подходящий

Ваша входная строка является допустимым кодом Python, поэтому, если строка не получена из пользовательского ввода, вы можете удобно выполнить ее как код Python, чтобы заполнить пустой dict как пространство имен локальных имен, чтобы его можно было распаковать как аргументы ключевого слова для вызова YouTube(url).streams.filter:

args = "progressive=True"
namespace = {}
exec(args, {}, namespace)
YouTube(url).streams.filter(**namespace)

OTOH, если оно не получено из внешних источников, предоставленных пользователем, тогда зачем вообще использовать строку, а не диктовку…?

deceze 05.08.2024 11:22

Ну, строка может, например, быть получена из файла конфигурации на защищенном хосте, но да, вполне вероятно, что строка предоставлена ​​пользователем. Просто я бы предложил этот подход для полноты картины.

blhsing 05.08.2024 11:27

Спасибо, это работает! Я до сих пор не совсем понимаю, почему это должен быть словарь всего, но это работает!

reChords 06.08.2024 09:17

@reChords Всегда пожалуйста. Еще раз имейте в виду, что это решение будет небезопасным, если строка будет получена из пользовательского ввода. Переменные аргументы ключевого слова представляют собой несколько пар имя-значение, поэтому было естественно решено, что dict будет наиболее подходящей структурой данных для их представления.

blhsing 06.08.2024 09:21

Другие вопросы по теме