Det här låter som ett bra användningsfall för en python kontexthanterare
. Med kontexthanterare kan du hantera resurser på rätt sätt , till exempel en databasanslutning, genom att låta dig ange hur din resurs inställnings- och rivningsmetoder ska fungera . Du kan skapa din egen anpassade kontexthanterare på ett av två sätt:För det första genom att slå in din databasklass och implementera de metoder som krävs för kontexthanteraren:__init__()
, __enter__()
, och __exit__()
. För det andra genom att använda en @contextmanager
decorator på en funktionsdefinition och skapa en generator för din databasresurs inom nämnda funktionsdefinition. Jag kommer att visa båda tillvägagångssätten och låta dig bestämma vilken som är din preferens. __init__()
metod är initieringsmetoden för din anpassade sammanhangshanterare, liknande initialiseringsmetoden som används för anpassade pythonklasser. __enter__()
metod är din installationskod för din anpassade sammanhangshanterare. Till sist, __exit()__
metoden är din nedbrytning kod för din anpassade sammanhangshanterare. Båda metoderna använder dessa metoder med den största skillnaden är att den första metoden uttryckligen kommer att ange dessa metoder inom din klassdefinition. Där som i den andra metoden, all kod upp till din generators yield
uttalandet är din initierings- och inställningskod och all kod efter yield
uttalande är din rivningskod. Jag skulle också överväga att extrahera dina användarbaserade databasåtgärder i en användarmodellklass också. Något i stil med:
anpassad kontexthanterare:(klassbaserad metod ):
import pymysql
class MyDatabase():
def __init__(self):
self.host = '127.0.0.1'
self.user = 'root'
self.password = ''
self.db = 'API'
self.con = None
self.cur = None
def __enter__(self):
# connect to database
self.con = pymysql.connect(host=self.host, user=self.user, password=self.password, db=self.db, cursorclass=pymysql.cursors.DictCursor, autocommit=True)
self.cur = self.con.cursor()
return self.cur
def __exit__(self, exc_type, exc_val, traceback):
# params after self are for dealing with exceptions
self.con.close()
user.py (refaktorerad) :'
# import your custom context manager created from the step above
# if you called your custom context manager file my_database.py: from my_database import MyDatabase
import <custom_context_manager>
class User:
def getUser(self, id):
sql = 'SELECT * from users where id = %d'
with MyDatabase() as db:
db.execute(sql, (id))
result = db.fetchall()
return result
def getAllUsers(self):
sql = 'SELECT * from users'
with MyDatabase() as db:
db.execute(sql)
result = db.fetchall()
return result
def AddUser(self, firstName, lastName, email):
sql = "INSERT INTO `users` (`firstName`, `lastName`, `email`) VALUES (%s, %s, %s)"
with MyDatabase() as db:
db.execute(sql, (firstName, lastName, email))
sammanhangshanterare (inredare) :
from contextlib import contextmanager
import pymysql
@contextmanager
def my_database():
try:
host = '127.0.0.1'
user = 'root'
password = ''
db = 'API'
con = pymysql.connect(host=host, user=user, password=password, db=db, cursorclass=pymysql.cursors.DictCursor, autocommit=True)
cur = con.cursor()
yield cur
finally:
con.close()
Sedan inom din User
klass kan du använda kontexthanteraren genom att först importera filen och sedan använda den på samma sätt som tidigare:
with my_database() as db:
sql = <whatever sql stmt you wish to execute>
#db action
db.execute(sql)
Förhoppningsvis hjälper det!