Python - Pourquoi est-ce une variable de classe ne sont pas définis dans la méthode?
J'ai une application en python qui est comme suit:
global_counter = 0
connections = {}
class SocketHandler():
currentid = 0
def open(self):
global global_counter
global connections
currentid = global_counter
global_counter += 1
connections[currentid] = self
print "WebSocket " + str(currentid) + " opened"
def on_close(self):
global connections
print "WebSocket " + str(currentid) + " closed"
del connections[currentid]
J'obtiens le message d'erreur:
NameError: global name 'currentid' is not defined
sur les lignes de "ouvert" et "on_close" où j'ai l'impression que je suis de l'ouverture/fermeture de la connexion. J'ai défini dans la classe, pourquoi n'est-il pas dans le champ d'application. Aussi, j'ai lu que l'utilisation de variables globales est mauvais, mais je ne vois pas un moyen de contourner cela. Quelqu'un peut-il préciser ce que je dois faire? Merci.
Utilisation de l'auto.currentid
OriginalL'auteur Lylax | 2012-10-08
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas accès implicite à des attributs à l'intérieur de méthodes, en Python.
Nue un nom comme
currentid
dans la ligne:toujours à la recherche d'un nom dans les locaux de la portée de la fonction, puis dans chaque fonction englobante portée, avant d'essayer le module global de la portée (et puis regarde built-ins en dernier recours).
currentid
est un attribut de classe, qui ne se trouve dans aucun de ces étendues.Pour rechercher un attribut en Python vous toujours besoin de spécifier un objet dans lequel chercher. Bien que le protocole de recherche signifie que l'objet ne doivent pas nécessairement avoir l'attribut lui-même; l'attribut de recherche revient à la classe de l'objet que vous avez spécifié (et les classes de base, si l'héritage est en jeu).
Donc, ce serait du travail:
Cependant, je ne pense pas que le reste de votre code fait ce que vous pensez qu'il est. Cette ligne dans le
open
méthode:ne définit pas le
currentid
attribut de votreSocketHandler
objet. L'affectation à un nu nom toujours assigne à une variable locale, sauf si vous explicitement déclarerglobal
(vous semblent être conscients de cela, puisque vous avez utilisé leglobal
mot-clé). Ainsi, dans leopen
méthode,currentid
est une fonction de la variable, sa valeur est perdu à la fin de laopen
méthode.En fait, votre
SocketHandler
objets n'ont pas decurrentid
attribut à tous (sauf si il y a plus de code que vous n'avez pas montré). Mettrecurrentid = 0
dans la classe du bloc n'est pas donner à tous leSocketHandler
cascurrentid
attribut. Il donne laSocketHandler
classe lui-même un attributcurrentid
; c'est juste que ledef open(self):
bloc crée uneopen
attribut (stockage d'une fonction) sur la classe de l'objet, et non pas sur chaque instance.Lecture
self.currentid
dans leon_close
méthode ne parviennent pas à trouver uncurrentid
attribut dans l'objetself
, de sorte que Python va regarder la classe deself
qui estSocketHandler
. Cet objet ne ont uncurrentid
valeur, de sorte que le résultat de la lectureself.currentid
sera0
, si oui ou non vous avez déjà exécutéopen
sur queSocketHandler
.Si vous destiné à stocker les
currentid
comme une variable d'instance dans chaqueSocketHandler
, puis la ligne dansopen
devra être:Il attribue à la
currentid
attribut de l'objet visé parself
. Vous aussi, vous avez besoin de changer toutes les autres références àcurrentid
dans vos méthodes deself.currentid
.OriginalL'auteur Ben
currentid
devrait êtreself.currentid
car il est une variable de classe.Pourquoi est-ce que beaucoup upvoted? -- le code dans le exampe ci-dessus n'aura plus de rupture avec NameError, mais de rompre avec une grave erreur de logique, si seulement ce remplacement est effectué.
Que voulez-vous dire? Les seules autres variables qui sont modifiées globals.
Quelle est la probabilité pensez-vous, c'est que l'OP doit avoir une variable locale avec le même nom que l'attribut de classe à l'intérieur de la
open
méthode? Et pour avoir leon_close
méthode toujoursdel connections[0]
?Désolé, j'ai lu jsbueno commentaire en disant qu'il y aura une erreur d'analyse dans le script, pas une erreur d'exécution.
OriginalL'auteur ronak
currentid
est l'instance de l'attribut, afin de l'utiliserself.currentid
au lieu decurrentid
:OriginalL'auteur defuz