2013-06-19 20 views
20

Jestem całkiem nowy, Python, tu jest jakiś kod patrzę:Korzystanie zmienną w try, catch, finally bez deklarowania go poza

try: 
    connection = getConnection(database) 
    cursor = connection.cursor() 
    cursor.execute("some query") 
except: 
    log.error("Problem.") 
    raise 
finally: 
    cursor.close() 
    connection.close() 

Czy to czyszczone prawidłowo? W innych językach, w których napisałem, jestem przyzwyczajony do robienia czegoś takiego:

connection = None 
cursor = None 

try: 
    connection = getConnection(database) 
    cursor = connection.cursor() 
    cursor.execute("some query") 
except: 
    log.error("Problem.") 
    raise 
finally: 
    if cursor is not None: 
     cursor.close() 
    if connection is not None:  
     connection.close() 

Odpowiedz

35

Python nie ma zasięgu bloku. Cokolwiek zdefiniowane wewnątrz bloku try będzie dostępne na zewnątrz.

Powiedział, że nadal masz problem: czy to jest wezwanie getConnection() że podnosi błąd, cursor będzie niezdefiniowane, więc odniesienie w bloku finally będzie błędów.

+2

Mam nadzieję, że to ma sens, ale "jak daleko" jest dostępne ? Zakładam, że funkcja ta będzie go zawierała, a co z instrukcjami i pętlami? – Cheetah

+1

Jeśli cały blok znajduje się w funkcji, jest on dostępny od tej chwili do końca funkcji. Jeśli jest na poziomie modułu, jest dostępny globalnie w tym module. Jeśli instrukcje i pętle nie wprowadzają nowego zakresu. –

6

Sugeruję użyciu kontekstów, takich jak:

from contextlib import closing 

try: 
    with closing(getConnection(database)) as connection: 
     with closing(connection.cursor()) as cursor: 
      cursor.execute("some query") 
except: 
    log.error("Problem") 
    raise 

Należy upewnić się, że zamknięcie (patrz more here). W niektórych przypadkach nie będziesz potrzebować closing, ponieważ połączenie najprawdopodobniej będzie obsługiwać sam protokół kontekstowy, więc będzie to tylko with getConnection(database)...

Powiązane problemy