Как найти самое первое назначение переменной в python с помощью ast

Я пытаюсь найти самое первое значение присваивания переменной, используя ast. например

import datetime
from airflow import DAG
from airflow.operators.dummy_operator import DummyOperator
from airflow.providers.postgres.hooks.postgres import PostgresHook
from airflow.providers.google.cloud.transfers.postgres_to_gcs import PostgresToGCSOperator
from airflow.providers.google.cloud.transfers.gcs_to_bigquery import GCSToBigQueryOperator
from airflow.operators.bash_operator import BashOperator

pg_connection0 = "airflow_db1"
pg_connection=pg_connection0

with DAG("demo_processing_dag",
            start_date=datetime.datetime(2021, 1, 1),
            schedule_interval=None) as dag:

        task1 = BashOperator(
                task_id = "dag_report",
                bash_command = "airflow dags report --output json >> /home/airflow/gcs/data/parse.json"
            )
        postgres_to_gcs_task = PostgresToGCSOperator(
            task_id=f'postgres_to_gcs',
            postgres_conn_id=pg_connection,
            sql=f'SELECT * FROM public.dag_code;',
            bucket = "mybucket",
            filename=f'data/dag_code.csv',
            export_format='csv',
            gzip=False,
            use_server_side_cursor=False,
        )

Мне нужен вывод как postgres_conn_id="airflow_db1"

Я пытался исследовать библиотеку ast, но получаю результат как pg_connection="pg_connection0"

ниже код, который я пробовал.

import ast

input_code = """
import datetime
from airflow import DAG
from airflow.operators.dummy_operator import DummyOperator
from airflow.providers.postgres.hooks.postgres import PostgresHook
from airflow.providers.google.cloud.transfers.postgres_to_gcs import PostgresToGCSOperator
from airflow.providers.google.cloud.transfers.gcs_to_bigquery import GCSToBigQueryOperator
from airflow.operators.bash_operator import BashOperator

pg_connection0 = "airflow_db1"
pg_connection=pg_connection0

with DAG("demo_processing_dag",
            start_date=datetime.datetime(2021, 1, 1),
            schedule_interval=None) as dag:

        task1 = BashOperator(
                task_id = "dag_report",
                bash_command = "airflow dags report --output json >> /home/airflow/gcs/data/parse.json"
            )
        postgres_to_gcs_task = PostgresToGCSOperator(
            task_id=f'postgres_to_gcs',
            postgres_conn_id=pg_connection,
            sql=f'SELECT * FROM public.dag_code;',
            bucket = "mybucket",
            filename=f'data/dag_code.csv',
            export_format='csv',
            gzip=False,
            use_server_side_cursor=False,
        )
"""

ast_tree = ast.parse(input_code)

# find the variable assignment for postgres_conn_id and extract its value
for node in ast.walk(ast_tree):
    if isinstance(node, ast.Assign) and node.targets[0].id == 'pg_connection':
        if isinstance(node.value, ast.Name):

            postgres_conn_id = node.targets[0].id + ' = "' + node.value.id + '"'
        else:
            print( node.value.s)
            postgres_conn_id = node.targets[0].id + ' = "' + node.value.s + '"'
        break

# print the output
print(postgres_conn_id)

Это не присвоение переменной. Это именованный аргумент функции.

Barmar 11.04.2023 19:26

Как я могу получить желаемый результат Бармар

cloud_anny 11.04.2023 19:27

И чтобы получить значение "airflow_db1", вам также необходимо моделировать поток данных, запоминая каждое назначение и сопоставляя его с источником.

Barmar 11.04.2023 19:28

Я не очень хорошо знаю библиотеку AST. Но вы должны искать узлы вызова функций, а не узлы назначения.

Barmar 11.04.2023 19:29
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пройдитесь по узлам дерева, пока не найдете присваивание константе.

for node in ast.walk(ast_tree):
    if isinstance(node, ast.keyword) and node.arg == 'postgres_conn_id':
        value = node.value
        while True:
            for node2 in ast.walk(ast_tree):
                if not isinstance(node2, ast.Assign):
                  continue
                if node2.targets[0].id == value.id:
                   value = node2.value
                   break
            if isinstance(value, ast.Constant):
                break

        print(f'{node.arg} = "{value.value}"')

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