Question

J'essaie de créer un assistant de génération de personnage pour un jeu. Dans une classe, je calcule les attributs du personnage. Dans une classe différente, j'indique à l'utilisateur quelles spécialités sont disponibles en fonction des attributs du personnage. Cependant, je ne me souviens plus comment passer des variables entre différentes classes.

Voici un exemple de ce que j'ai:

class BasicInfoPage(wx.wizard.WizardPageSimple):            
    def __init__(self, parent, title):
         wiz.WizardPageSimple.__init__(self, parent)
         self.next = self.prev = None
         self.sizer = makePageTitle(self, title)

                    <---snip--->

         self.intelligence = self.genAttribs()

class MOS(wx.wizard.WizardPageSimple):
     def __init__(self, parent, title):
         wiz.WizardPageSimple.__init__(self, parent)
         self.next = self.prev = None
         self.sizer = makePageTitle(self, title)
      def eligibleMOS(self, event):
          if self.intelligence >= 12: 
               self.MOS_list.append("Analyst")

Le problème est que je ne vois pas comment utiliser l'intelligence " variable de la classe BasicInfoPage vers la classe MOS. J'ai essayé plusieurs choses sur Internet mais rien ne semble fonctionner. Qu'est-ce qui me manque?

Modifier Après avoir posté ce message, j'ai réalisé que je ne l'expliquais pas très bien. J'essaie de créer une version informatique du jeu de rôle Twilight 2000 des années 1980.

J'utilise wxPython pour créer un assistant. la classe parente de mes classes est l'assistant de wxPython. Cet assistant guidera un utilisateur tout au long de la création d'un caractère. La page Informations de base (classe BasicInfoPage) permet à l'utilisateur de donner le nom du caractère et son caractère "déroulant". pour les attributs du personnage. C’est là que le "self.intelligence" vient de.

J'essaie d'utiliser les attributs qui lui ont été créés pour une page plus loin dans l'assistant, dans laquelle l'utilisateur sélectionne la spécialité du personnage. Les spécialités disponibles dépendent des attributs du personnage, par exemple: si l'intelligence est suffisamment élevée, le personnage peut être un Intel Anaylst.

Cela fait plusieurs années que j'ai programmé, en particulier avec des idées de POO. C'est pourquoi je ne comprends pas comment créer ce qui est essentiellement une variable globale avec des classes et des méthodes.

Était-ce utile?

La solution

Vous pouvez avoir "Classe". et " Instance " confus. Ce n'est pas clair dans votre exemple. Je présume donc que vous utilisez beaucoup de définitions de classe et que vous ne disposez pas d'instances d'objet appropriées pour ces classes.

Les classes n'ont pas vraiment de valeurs d'attributs utilisables. Une classe est simplement un ensemble commun de définitions pour une collection d'objets. Vous devriez considérer les classes comme des définitions et non comme des choses réelles.

Les instances de classes, les "objets", sont des objets réels qui ont des valeurs d'attribut et des fonctions de méthode d'exécution.

Vous ne transmettez pas de variables entre classes . Vous transmettez des variables entre instances . En pratique, seules les variables d'instance importent. [Oui, il existe des variables de classe, mais elles constituent une chose assez spécialisée et souvent déroutante, qu'il vaut mieux éviter.]

Lorsque vous créez un objet (une instance d'une classe)

b= BasicInfoPage(...)

Alors b.intelligence est la valeur d'intelligence pour l'instance b de BasicInfoPage .

Une chose vraiment commune est

class MOS( wx.wizard.PageSimple ):
    def __init__( self, parent, title, basicInfoPage ):
        <snip>
        self.basicInfo= basicInfoPage

Désormais, dans les méthodes MOS, vous pouvez dire self.basicInfo.intelligence car MOS dispose d'un objet doté d'une page d'informations de base.

Lorsque vous créez une MOS, vous lui fournissez l'instance de BasicInfoPage qu'elle est censée utiliser.

someBasicInfoPage= BasicInfoPage( ... ) 
m= MOS( ..., someBasicInfoPage )

Maintenant, l'objet m peut examiner someBasicInfoPage.intelligence

Autres conseils

Chaque page d'un assistant - en elle-même - ne devrait pas être le conteneur des informations que vous collectez.

Consultez le modèle de conception Model-View-Control . Vos pages ont les parties Voir et Contrôler de la conception. Cependant, ils ne sont pas le modèle de données.

Vous serez plus heureux si vous avez un objet distinct qui est "construit". par les pages. Chaque page définira certains attributs de cet objet de modèle sous-jacent. Ensuite, les pages sont indépendantes les unes des autres, car toutes les pages obtiennent et définissent les valeurs de cet objet de modèle sous-jacent.

Puisque vous construisez un personnage, vous auriez une classe comme celle-ci

class Character( object ):
    def __init__( self ):
        self.intelligence= 10
        <default values for all attributes.>

Ensuite, il vous suffit de donner à l'objet Character sous-jacent un emplacement pour placer et obtenir des valeurs dans vos différentes instances de l'Assistant.

Mon problème était bien la confusion entre les classes et les instances. J'essayais de tout faire via les classes sans jamais créer une instance réelle. De plus, je forçais le "BasicInfoPage". classe de faire trop de travail.

Finalement, j'ai créé une nouvelle classe ( BaseAttribs ) pour contenir toutes les variables dont j'ai besoin. J'ai ensuite créé une instance de cette classe lorsque j'exécute l'assistant et passe cette instance sous forme d'argument aux classes qui en ont besoin, comme indiqué ci-dessous:

#---Run the wizard
if __name__ == "__main__":
    app = wx.PySimpleApp()
    wizard = wiz.Wizard(None, -1, "TW2K Character Creation")
    attribs = BaseAttribs

#---Create each page
    page1 = IntroPage(wizard, "Introduction")
    page2 = BasicInfoPage(wizard, "Basic Info", attribs)
    page3 = Ethnicity(wizard, "Ethnicity")
    page4 = MOS(wizard, "Military Occupational Specialty", attribs)

J'ai ensuite utilisé les informations fournies par S.Lott et créé des instances individuelles (si c'est ainsi qu'il s'appelle) au sein de chaque classe; chaque classe accède aux mêmes variables cependant.

Tout fonctionne, autant que je sache. Merci.

Tout ce dont vous avez besoin est une référence. Ce n'est pas vraiment un problème simple auquel je peux donner une solution sur une ligne (autre qu'un simple vilain mondial qui briserait probablement autre chose), mais un problème de structure de programme. Comme par magie, vous n'avez pas accès à une variable créée sur une autre instance d'une autre classe. Vous devez soit donner la référence de l'intelligence à MOS, soit la prendre à partir de BasicInfoPage, peu importe la situation. Il me semble que les classes sont conçues assez bizarrement - une page d’information, par exemple, ne devrait rien générer, et si c’est le cas, elle devrait la restituer à ceux qui en ont besoin - une sorte de lieu central, qui aurait dû être celui qui le génère en premier lieu. Normalement, vous définissez les variables ici et les récupérez à partir de là. Ou du moins, je le ferais.

Si vous souhaitez connaître la réponse de base: "comment puis-je passer des variables entre différentes classes"?, voilà, mais je doute que ce soit exactement ce que vous voulez, car vous envisagez d'utiliser une sorte de cadre de contrôle:

class Foo(object):
    def __init__(self, var):
        self.var = var

class Bar(object):
    def do_something(self, var):
        print var*3

if __name__ == '__main__':
    f = Foo(3)
    b = Bar()
    # look, I'm using the variable from one instance in another!
    b.do_something(f.var)

Si je vous ai bien compris, la réponse est: vous ne pouvez pas.

l'intelligence devrait être un attribut de WizardPageSimple, si vous voulez que les deux classes l'héritent.

Selon votre situation, vous pouvez essayer d'extraire des informations et des attributs connexes dans une autre classe de base. Ensuite, vous pouvez hériter des deux:

class MOS(wiz.WizardPageSimple, wiz.IntelligenceAttributes): # Or something like that.

Dans ce cas, vous devez utiliser le super coopératif. En fait, vous devriez déjà l'utiliser. Au lieu d'appeler

wiz.WizardPageSimple.__init__(self, parent)

appeler

super(MOS, self).__init__(self, parent)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top