2009-05-24 7 views
14

Ayant juste retiré mes cheveux en raison d'une différence, j'aimerais savoir quelle est la différence est en Python 2.5.L'instruction 'with' de Python versus 'with .. as'

J'avais deux blocs de code (dbao.getConnection() renvoie une connexion MySQLdb).

conn = dbao.getConnection() 
with conn: 
    # Do stuff 

Et

with dbao.getConnection() as conn: 
    # Do stuff 

Je pensais que ce serait le même effet, mais apparemment pas l'objet conn de cette dernière version était un Cursor. D'où vient le curseur et y at-il un moyen de combiner l'initialisation de la variable et l'instruction en quelque sorte?

+4

La deuxième version initialise une variable, conn. Quel problème réel avez-vous? Ce qui a fonctionné différemment? Quelle erreur avez-vous obtenu? Pouvez-vous inclure une sortie pour montrer le problème? –

+0

Désolé. Pensé qu'il aurait été clair à partir de la description. dbao.getConnection() retourne une connexion MySQLdb donc conn = dbao.getConnection() a pour résultat un conn étant un objet Connection alors que "avec dbao.getConnection() comme conn" entraîne un objet Cursor.Le message d'erreur était que dans ce dernier cas conn ne disposait pas d'une méthode d'annulation qu'il ne devrait pas avoir car il s'agissait d'un curseur. –

Répondre

1

L'instruction with est là pour permettre par exemple de s'assurer que la transaction est démarrée et arrêtée correctement.

Dans le cas de connexions de base de données en python, je pense que la chose naturelle à faire est de créer un curseur au début de l'instruction avec puis valider ou annuler la transaction à la fin de celle-ci.

Les deux blocs que vous avez donnés sont identiques du point de vue de l'instruction. Vous pouvez aussi bien ajouter l'as au premier et obtenir le curseur.

Vous devez vérifier comment le support est implémenté dans l'objet avec lequel vous l'utilisez.

Voir http://docs.python.org/whatsnew/2.5.html#pep-343-the-with-statement

29

Il peut être un peu déroutant au premier coup d'œil, mais

with babby() as b: 
    ... 

est pas équivalent à

b = babby() 
with b: 
    ... 

Pour voir pourquoi, voici comment serait mis en œuvre le gestionnaire de contexte:

class babby(object): 
    def __enter__(self): 
     return 'frigth' 

    def __exit__(self, type, value, tb): 
     pass 

Dans le premier cas, le nom b sera lié à tout ce qui est renvoyé par la méthode __enter__ du gestionnaire de contexte. C'est souvent le gestionnaire de contexte lui-même (par exemple pour les objets de fichier), mais ce n'est pas obligatoire; dans ce cas, c'est la chaîne 'frigth', et dans votre cas c'est le curseur de la base de données.

Dans le second cas, b est l'objet du gestionnaire de contexte lui-même.

+0

Dans des moments comme ceux-ci, j'aimerais pouvoir attribuer deux réponses. : | –

+1

@Mikko: À mon humble avis, c'est le mieux - si ce n'est pas pour d'autres raisons que c'est plus détaillé et discute les différences - répondre et devrait être le accepté. – martineau

+0

@martineau: Puisque nous commenterons de vieux commentaires! Oui, cette réponse est plus détaillée et discute des différences. Il donne plus d'informations générales et dans ce sens c'est mieux. Mais en guise de réponse, c'est à l'envers. La réponse acceptée parvient à répondre à la question spécifique dans les (premières) deux lignes. Avec celui-ci j'ai besoin de lire des exemples de cas, etc. avant de recevoir une réponse à la question. Une réponse parfaite aurait la réponse acceptée comme le premier paragraphe suivi de celui-ci. L'information de fond est agréable, mais parfois c'est rafraîchissant d'avoir la réponse. –

Questions connexes