У меня есть выражение Python, которое выглядит следующим образом:
var1 = 'GOOGLE'
var2 = '5'
expr = 'df[df[var1]>=var2]'
В моей рабочей области var1 и var2 определены правильно, поэтому я могу оценить expr следующим образом:
eval(expr)
Однако я хочу передать это выражение (в виде строки) другой функции с заменой в ней значений var1 и var2. Я не хочу передавать переменные var1 и var2, так как у меня может быть любое количество переменных, а не только две. Как мне это сделать?
Я бы использовал словарь или пользовательский объект, чтобы собрать все переменные, которые вы хотите передать своей функции, в один входной аргумент. Подойдет ли это для вашей проблемы?
Какой у Вас вопрос? Пока ваш вопрос не ясен. Вы хотите знать, как создать функцию, которая принимает различные (любое количество) аргументы или что?
@PieCot Да, это возможное решение, но я хочу, чтобы переменные были заменены, чтобы человеку, выполняющему задачу ниже по течению, не нужно было беспокоиться о замене переменных.
@MaxwellD.Dorliea: я просто хочу преобразовать строку df[df[var1]>=var2] в df[df['GOOG']>=5] без ее оценки.
@Zing Просто используйте f-строку
Еще одно очень глупое решение — использование replace
, но, на мой взгляд, очень опасное: expr.replace('var1', f"'{var1}'").replace('var2', var2)
. Я бы не стал его использовать. Ясно, что вы можете автоматизировать, перебирая все переменные, которые хотите заменить.
@flakes: Спасибо, что потратили время, чтобы сообщить мне, что это проблема XY.
@Zing Я ответил на твой вопрос?
@MaxwellD.Dorliea: Это похоже на решение, но мне потребуется добавить фигурные скобки в выражение, прежде чем я его использую. Спасибо.
@Zing не забудь отметить как правильный✅ если я отвечу на твой вопрос
Вы можете просто использовать f-строку Python, как показано ниже.
expr = f'df[df[{var1}] >= {var2}]'
Это возможное решение, но мне потребуется добавить фигурные скобки вокруг переменных, которых я хотел избежать.
Вы можете проанализировать выражение с помощью ast.parse
и использовать подкласс ast.NodeTransformer
для преобразования узлов Name
в соответствующие значения в виде узлов Constant
, а затем преобразовать AST обратно в код с помощью ast.unparse
:
import ast
var1 = 'GOOGLE'
var2 = '5'
expr = 'df[df[var1]>=var2]'
class NamesToConstants(ast.NodeTransformer):
def visit_Name(self, node):
if node.id in globals(): # feel free to use your own dict instead of globals()
value = globals()[node.id]
try: # convert value to integer if viable
value = int(value)
except:
pass
return ast.Constant(value=value)
return node
tree = ast.parse(expr)
NamesToConstants().visit(tree)
print(ast.unparse(tree))
Это выводит:
df[df['GOOGLE'] >= 5]
ast.unparse
требуется Python 3.10 или новее. Если вы используете более раннюю версию, вместо этого вы можете использовать astunparse.unparse
из пакета astunparse.