2012-09-30 4 views
0

Je définit deux classes dans le même module et que vous souhaitez utiliser le second dans le premier (comme une variable globale):objet ne peut pas être créée de manière globale, mais peut localement python

class Class1(object): 
    global_c2 = Class2() 

    def foo(self): 
     local_c2 = Class2() 

class Class2(object): 
    pass 

global_c2 obtient une erreur mais local_c2 ne le fait pas. Cela est logique car lorsque le compilateur regarde à travers ce fichier, il ne sait pas que Class2 va exister. De plus, si je change de classe pour que Class2 soit défini en premier, cela fonctionne.

Cependant, je me demandais s'il y a une autre façon de contourner ce problème. Peut-être que je peux dire à Python que Class2 va exister, alors ne vous en faites pas, ou dois-je simplement les mettre dans le bon ordre?

+0

indenter votre code correctement. –

+0

@AshwiniChaudhary Il est indenté correctement. Eh bien, l'argument 'self' fait allusion à' foo' étant destiné à être une méthode, mais cela fonctionne dans les deux cas et illustre le problème d'une manière ou d'une autre. – delnan

+0

d'où vient la fonction 'foo()'? –

Répondre

1

Le compilateur ne fait rien ici. Dans les deux cas, exactement la même séquence de bytecode est générée à regardez la classe à l'exécution et instancier

ce qui fait la différence est lorsque les états sont Rassemblez tous les code dans un module Python est exécuté en haut du bas -.. il n'y a pas une telle chose comme une déclaration, tout est une définition et chaque liaison est dynamique.Le code dans une définition de classe est exécuté lorsque la définition de classe est rencontrée (et avant vant la deuxième classe est mis en existence et lié au nom Class2). Le code d'une fonction s'exécute lorsque la fonction est appelée, et parce que vous n'appelez pas la fonction avant la définition de la deuxième classe, elle est disponible au moment où vous appelez cette fonction.

C'est essentiellement ce que chaque solution se résume à: Retard tenant jusqu'à ce que tout ce que vous lier à existe.

+0

Merci, c'est l'explication que je cherchais. J'espérais qu'il pourrait y avoir une façon de déclarer les Classes dans les fichiers __init__ mais je suppose qu '«il n'y a pas de déclaration» signifie que cela serait impossible. Merci – Paul

+0

En fait, vous ne devriez pas prendre « il n'y a pas une telle chose comme une déclaration » taht littéralement - il est vrai que vous ne devez pas déclarer des variables ou types pour ceux-ci, mais une classe, ou même un corps de la fonction _is_ une déclaration pour tous les effets. – jsbueno

+1

En outre, le framework Django, lorsqu'il est frappé par ce problème quand les gens construire leurs modèles d'objet orientés relation, ont opté pour cette solution: elle ne permet pour une référence de chaîne à une classe encore à être déclarés (par ex ('. attr = "Class2" ') au lieu de' attr = Class2'). Lors de l'utilisation de l'attribut, si son type est string, il obtient une référence à la classe réelle qui a ce nom sur le module. – jsbueno

1

Vous pouvez effectuer les opérations suivantes (c.-à remblayer le contenu de la classe 1 fois Classe2 a été déclarée.

class Class1(object): 
    pass 

class Class2(object): 
    pass 

Class1.global_c2 = Class2() 
+0

-1 Ce n'était pas la question. – delnan

+0

@delnan Cela contourne le problème de dépendance cyclique - merci pour le downvote: -/OP –

+0

décrit une solution au problème. Il n'y a pas non plus de dépendance cyclique ici. La question est tout à fait différente, à savoir * pourquoi * et quand cela est ou n'est pas un problème. – delnan

Questions connexes