Si j'ai le code python suivant:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
Il se plaint
NameError: global name 'bar' is not defined
Comment puis-je accéder à la classe / variable statique bar
dans la méthode bah
?
python
oop
static-variables
Ross Rogers
la source
la source
Réponses:
Au lieu d'
bar
utiliserself.bar
ouFoo.bar
. Assigner àFoo.bar
créera une variable statique, et assigner àself.bar
créera une variable d'instance.la source
Définissez la méthode de classe:
Maintenant, si
bah()
doit être une méthode d'instance (c'est-à-dire avoir accès à soi), vous pouvez toujours accéder directement à la variable de classe.la source
Comme pour tous les bons exemples, vous avez simplifié ce que vous essayez de faire. C'est bien, mais il convient de noter que python a beaucoup de flexibilité en ce qui concerne les variables de classe par rapport aux variables d'instance. On peut en dire autant des méthodes. Pour une bonne liste de possibilités, je vous recommande de lire l' introduction aux classes de nouveau style de Michael Fötsch , en particulier les sections 2 à 6.
Une chose qui demande beaucoup de travail à retenir lors de la mise en route est que python n'est pas java. Plus qu'un simple cliché. En java, une classe entière est compilée, rendant la résolution de l'espace de noms très simple: toutes les variables déclarées en dehors d'une méthode (n'importe où) sont des variables d'instance (ou, si statique, de classe) et sont implicitement accessibles dans les méthodes.
Avec python, la grande règle d'or est qu'il y a trois espaces de noms qui sont recherchés, dans l'ordre, pour les variables:
{begin pedagogy}
Il existe des exceptions limitées à cela. Le principal qui me vient à l'esprit est que, lorsqu'une définition de classe est en cours de chargement, la définition de classe est son propre espace de noms implicite. Mais cela ne dure que tant que le module est en cours de chargement, et est entièrement contourné dans une méthode. Donc:
mais:
{end pedagogy}
En fin de compte , la chose à retenir est que vous n'avez accès à l' une des variables que vous souhaitez accéder, mais probablement pas implicitement. Si vos objectifs sont simples et directs, opter pour Foo.bar ou self.bar sera probablement suffisant. Si votre exemple devient plus compliqué, ou si vous voulez faire des choses fantaisistes comme l'héritage (vous pouvez hériter de méthodes statiques / de classe!), Ou que l'idée de faire référence au nom de votre classe dans la classe elle-même vous semble erronée, consultez l'intro que j'ai liée.
la source
la source
la source