Инициализация переменной без присвоения значения. Python
Пожалуйста помогите, создал функцию, чтобы приконнектиться к БД, но есть проблема, я не могу дальше пользоваться переменной cursor, чтобы работать с бд.
def ConnectServer():
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username.get()+';PWD='+ password.get())
cursor = cnxn.cursor()
Вопрос: можно ли как-нибудь инициализировать эту переменную в основном коде, без присвоения ей значения?
P.S. Мне нужно, чтобы я мог обращаться к этой переменной при помощи global в функции и она была видна в основном коде
Код кнопки:
bb1 = Button(pas, text='Ввести', background="#555", foreground="#ccc", command=ConnectServer, font='Times 12 italic')
Полный код:
#######################################################################
#######################################################################
def ConnectServer():
global cursor
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username.get()+';PWD='+ password.get())
cursor = cnxn.cursor()
root.deiconify()
pas.withdraw()
#######################################################################
#######################################################################
###Подключение#К#БД###
root = Tk()
root.configure(background='#888')
root.title('СУБД')
root.geometry('1200x600+370+40')
root.withdraw()
server = 'LAPTOP-C0VE2QJR\SERVER'
database = 'Metropol'
username = StringVar()
password = StringVar()
username.set('admin')
password.set('password')
pas = Toplevel(background= "#888")
pas.title('Вход')
pas.geometry('300x300')
Labll = Label(pas, text='Введите логин', font='Times 12 italic', fg='#111')
Labll.grid(row=0, column=0, sticky=S, pady=30, padx=70)
Entr1 = Entry(pas, text='', textvariable=username, font='Times 12 bold', justify='center')
Entr1.grid(row=1, column=0, sticky=S, padx=70, pady=3)
Labl2 = Label(pas, text='Введите пароль', font='Times 12 italic', fg='#111')
Labl2.grid(row=2, column=0, sticky=S, pady=30, padx=70)
Entr2 = Entry(pas, text='', textvariable=password, font='Times 12 bold', justify='center')
Entr2.grid(row=3, column=0, sticky=S, padx=70, pady=3)
bb1 = Button(pas, text='Ввести', background="#555", foreground="#ccc", command=ConnectServer, font='Times 12 italic')
bb1.grid(row=4, column=0, sticky=S, padx=70, pady=10)
#######################################################################
###Вывод#Таблиц###
cursor.execute("SELECT Номер FROM ЛицевойСчет")
rows = cursor.fetchall()
print(rows)
Ответы (2 шт):
У вас непонимание, что такое global и как оно работает. Вы спокойно можете объявить переменную как global в функции и присвоить ей что нужно. Она будет далее видна в основной части программы и во всех функциях, где вы её также объявите как global. Никакого предварительного присваивания не нужно при этом.
def ConnectServer():
global cursor
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username.get()+';PWD='+ password.get())
cursor = cnxn.cursor()
Хотя в любом случае это неправильный шаблон работы с БД. Правильный шаблон - это открывать коннекшен, делать запрос, и закрывать коннекшен. Лучше автоматически - с помощью конструкции with. Современные БД сами следят за тем, чтобы быстро выдавать вам актуальный коннекшен из пула коннекшенов, если вы обращаетесь повторно к той же базе с тем же логином.
А такой шаблон работы, когда вы открываете коннекшен в одном месте, а используете в другом, может привести к различным проблемам. Например, что вы будете делать, если коннекшен прервётся? При нормальном шаблоне работы вам нужно в этом случае попытаться переоткрыть коннекшен и повторить операцию. А как вы это сделаете, если коннекшен вы открываете незнамо где, а вовсе не там, где работаете с базой?
Если объект создается внутри функции и присваивается глобальной переменной, то правильнее заранее объявить переменную как None, но использовать аннотацию, как в примере ниже Test: 'Class' = None. Тогда, например PyCharm, будет знать, что это за тип переменной, подтягивать и продолжать названия методов при использовании Test.метод вне функции init_test, сигнализировать при неправильном использовании переменной.
# ---module_1 ---
class Class:
def method(self):
return
...
# ---module_2 ---
import module_1
Test: 'module_1.Class' = None
def test():
global Test
Test = module_1.Class()
return
...
# ---module_3---
import module_2
module_2.Test.method()