Не передаются данные из функции python

Что то я понять не могу, почему такой вариант кода не работает. Я же в функции execute_db() вызываю connect_db(), почему переменные в таком случае не передаются?

import mysql.connector

def connect_db():
    connect = mysql.connector.connect(host='IP', user='USER', password='PASS', database='DB')
    cursor = connect.cursor()


def execute_db(query):
    connect_db()
    cursor.execute(query)
    data = cursor.fetchall()
    connect.close()
    
    return data


data = execute_db("SELECT * FROM logs")
print(data)



Traceback (most recent call last):
  File "c:\Users\Timur\Desktop\Григорий\test.py", line 17, in <module>
    data = execute_db("SELECT * FROM logs")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\Timur\Desktop\Григорий\test.py", line 10, in execute_db
    cursor.execute(query)
    ^^^^^^
NameError: name 'cursor' is not defined

MysqlConnect.py

import mysql.connector


class MysqlConnect(object):
    def __init__(self, host, user, password, database, port=3306) -> None:
        self.host = host
        self.user = user
        self.password = password
        self.database = database
        self.port = port


    def connect_db(self) -> None:
        self.connect = mysql.connector.connect(host = self.host, user = self.user, password = self.password, database = self.database, port = self.port)
        self.cursor = self.connect.cursor()


    def execute_db(self, query) -> dict:
        self.cursor.execute(query)
        self.data = self.cursor.fetchall()
        self.connect.close()
        
        return self.data
        

main.py

import MysqlConnect


connect = MysqlConnect.MysqlConnect(host='', user='', password='', database='')

data = connect.execute_db('SELECT * FROM logs')

print(data)



Traceback (most recent call last):
  File "c:\Users\admin\Desktop\py\main.py", line 6, in <module>
    data = connect.execute_db('SELECT * FROM logs')
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\admin\Desktop\py\MysqlConnect.py", line 19, in execute_db
    self.cursor.execute(query)
    ^^^^^^^^^^^
AttributeError: 'MysqlConnect' object has no attribute 'cursor'
PS C:\Users\admin\Desktop\py> 

Ответы (1 шт):

Автор решения: CrazyElf

В данном случае нужно возвращать переменные из функции и принимать их в вызывающей функции:

def connect_db():
    ...
    return connect, cursor

def execute_db(query):
    connect, cursor = connect_db()
    ...

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

Суть в том, что переменные внутри функции локальные. Вернее, в питоне всё сложнее. В функции можете читать глобальные переменные, но не можете их писать без явного указания, что они global. Но лучше на глобальные переменные и не завязываться. Хорошая функция - "чистая" функция. Т.е. та, которая получает все аргументы в явном виде и отдаёт результаты тоже в явном виде через return.

→ Ссылка