Domanda

Sto cercando di creare una procedura guidata di generazione del personaggio per un gioco. In una classe calcolo gli attributi del personaggio. In una classe diversa, sto mostrando all'utente quali specialità sono disponibili in base agli attributi del personaggio. Tuttavia, non ricordo come passare le variabili tra classi diverse.

Ecco un esempio di ciò che ho:

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")

Il problema è che non riesco a capire come usare la "intelligence" variabile dalla classe BasicInfoPage alla classe MOS. Ho provato diverse cose da Internet, ma nulla sembra funzionare. Cosa mi sto perdendo?

Modifica Mi sono reso conto dopo aver pubblicato questo che non l'ho spiegato bene. Sto cercando di creare una versione per computer del gioco di ruolo Twilight 2000 degli anni '80.

Sto usando wxPython per creare una procedura guidata; la classe genitrice delle mie classi è la procedura guidata di wxPython. Quella procedura guidata guiderà un utente attraverso la creazione di un personaggio, quindi la pagina Informazioni di base (classe BasicInfoPage) consente all'utente di dare il nome del personaggio e " roll " per gli attributi del personaggio. Ecco dove il "self.intelligence" viene da.

Sto cercando di utilizzare gli attributi creati per una pagina più avanti nella procedura guidata, in cui l'utente seleziona la specialità del personaggio. Le specialità disponibili dipendono dagli attributi del personaggio, ad es. se l'intelligenza è abbastanza alta, il personaggio può essere un Intel Anaylst.

Sono passati diversi anni da quando ho programmato, specialmente con idee OOP. Ecco perché sono confuso su come creare ciò che è essenzialmente una variabile globale con classi e metodi.

È stato utile?

Soluzione

Potresti avere " Classe " e "istanza" confuso. Non è chiaro dal tuo esempio, quindi presumo che stai usando molte definizioni di classe e non hai istanze di oggetti appropriate di quelle classi.

Le classi non hanno davvero valori di attributi utilizzabili. Una classe è solo un insieme comune di definizioni per una raccolta di oggetti. Dovresti pensare alle classi come a definizioni, non a cose reali.

Le istanze di classi, "oggetti", sono cose reali che hanno valori di attributo effettivi ed eseguono funzioni di metodo.

Non passi variabili tra le classi . Si passano variabili tra istanze . In pratica, contano solo le variabili di istanza. [Sì, ci sono variabili di classe, ma sono piuttosto specializzate e spesso confuse, meglio evitare.]

Quando si crea un oggetto (un'istanza di una classe)

b= BasicInfoPage(...)

Quindi b.intelligence è il valore dell'intelligence per l'istanza b di BasicInfoPage .

Una cosa davvero comune è

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

Ora, con i metodi MOS, puoi dire self.basicInfo.intelligence perché MOS ha un oggetto che è disponibile in BasicInfoPage.

Quando compili MOS, gli fornisci l'istanza di BasicInfoPage che dovrebbe usare.

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

Ora l'oggetto m può esaminare someBasicInfoPage.intelligence

Altri suggerimenti

Ogni pagina di una procedura guidata - da sola - non dovrebbe in realtà essere il contenitore per le informazioni che stai raccogliendo.

Leggi il modello di progettazione Model-View-Control . Le tue pagine hanno le parti di visualizzazione e controllo del progetto. Non sono il modello di dati, tuttavia.

Sarai più felice se hai un oggetto separato che è " costruito " dalle pagine. Ogni pagina imposterà alcuni attributi dell'oggetto modello sottostante. Quindi, le pagine sono indipendenti l'una dall'altra, poiché tutte le pagine ottengono e impostano i valori di questo oggetto modello sottostante.

Dato che stai costruendo un personaggio, avresti una classe come questa

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

Quindi le varie istanze della procedura guidata devono solo disporre dell'oggetto carattere sottostante come luogo in cui inserire e ottenere valori.

Il mio problema era davvero la confusione tra classi e istanze. Stavo cercando di fare tutto tramite le classi senza mai creare un'istanza reale. Inoltre, stavo forzando il "BasicInfoPage" classe per fare troppo lavoro.

Alla fine, ho creato una nuova classe ( BaseAttribs ) per contenere tutte le variabili di cui ho bisogno. Ho quindi creato l'istanza di quella classe quando eseguo la procedura guidata e passo quell'istanza come argomento alle classi che ne hanno bisogno, come mostrato di seguito:

#---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)

Ho quindi usato le informazioni fornite da S.Lott e creato singole istanze (se è così che si chiama) all'interno di ogni classe; ogni classe accede però alle stesse variabili.

Tutto funziona, per quanto ne so. Grazie.

Tutto ciò che serve è un riferimento. Non è proprio un problema semplice a cui posso dare una soluzione a una riga (a parte un semplice brutto globale che probabilmente spezzerebbe qualcos'altro), ma una struttura del programma. Non hai magicamente accesso a una variabile creata su un'altra istanza di un'altra classe. Devi dare il riferimento dell'intelligence a MOS o prenderlo da BasicInfoPage, tuttavia ciò potrebbe accadere. Mi sembra che le classi siano progettate in modo piuttosto strano - una pagina di informazioni, per prima cosa, non dovrebbe generare nulla, e se lo fa, dovrebbe restituirlo a tutto ciò che deve sapere - una sorta di posto centrale, che avrebbe dovuto essere quello che l'ha generato in primo luogo. Di solito, dovevi impostare le variabili lì, e prenderle da lì. O almeno lo farei.

Se vuoi la risposta di base di " come faccio a passare variabili tra classi diverse " ;, allora eccoti qui, ma dubito che sia esattamente quello che vuoi, dato che sembri usare una sorta di framework di controllo:

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)

Se ti ho capito correttamente, la risposta è: non puoi.

l'intelligenza dovrebbe essere un attributo di WizardPageSimple, se si desidera che entrambe le classi ereditino.

A seconda della situazione, potresti provare a estrarre l'intelligenza e gli attributi correlati in un'altra base. Quindi puoi ereditare da entrambi:

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

In tal caso devi utilizzare il super cooperativo. In effetti, dovresti già usarlo. Invece di chiamare

wiz.WizardPageSimple.__init__(self, parent)

chiamata

super(MOS, self).__init__(self, parent)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top