类之间的Python传递变量

时间:2020-03-06 14:31:30  来源:igfitidea点击:

我正在尝试为游戏创建角色生成向导。在一个类中,我计算角色的属性。在不同的类中,我要向用户显示基于字符属性的哪些专业可用。但是,我不记得如何在不同的类之间传递变量。

这是我所拥有的一个例子:

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

问题是我不知道如何使用从BasicInfoPage类到MOS类的" intelligence"变量。我从互联网上尝试了几种不同的方法,但是似乎没有任何效果。我想念什么?

编辑后,我发现我发布的内容并没有那么好解释。我正在尝试创建1980年代的Twilight 2000 RPG的计算机版本。

我正在使用wxPython创建向导;我类的父类是wxPython中的向导。该向导将引导用户完成角色的创建,因此"基本信息"页面(类BasicInfoPage)允许用户提供角色的名称和角色属性的"滚动"。那就是" self.intelligence"的来源。

我试图在向导中进一步使用页面创建的属性,用户可以在其中选择角色的特长。可用的专业取决于角色具有的属性,例如如果智力足够高,则角色可以是Intel Anaylst。

自从我编写程序已经有几年了,尤其是关于OOP的想法。这就是为什么我对如何使用类和方法创建本质上是全局变量的方法感到困惑。

解决方案

如果我对理解正确,那么答案是:我们不能。

如果我们希望两个类都继承它,则Intelligence应该是WizardPageSimple的属性。

根据情况,我们可能尝试将情报和相关属性提取到另一个基类中。然后,我们可以从两个继承:

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

在这种情况下,我们必须使用合作超级。实际上,我们应该已经在使用它。而不是打电话

wiz.WizardPageSimple.__init__(self, parent)

称呼

super(MOS, self).__init__(self, parent)

我们所需要的只是参考。我可以给出一些单行解决方案(不是一个简单的丑陋的全局变量,可能会破坏其他东西),这不是一个简单的问题,而是程序结构之一。我们无法神奇地访问在另一个类的另一个实例上创建的变量。我们必须为MOS提供智能参考,或者从BasicInfoPage中获取智能参考,但是这可能会发生。在我看来,这些类的设计很奇怪-一方面,一个信息页面不应该生成任何东西,如果生成了,则应该将其返回给需要知道的任何内容,例如某种中央位置,首先是它的产生者。通常,我们可以在此处设置变量,然后从那里获取变量。或者至少,我会的。

如果我们想要"如何在不同的类之间传递变量"的基本答案,那么就可以使用,但是我怀疑这正是我们想要的,因为我们希望使用某种控制框架:

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)

我们可能混淆了"类"和"实例"。从示例尚不清楚,因此我假设我们正在使用许多类定义,并且没有这些类的适当对象实例。

类实际上没有可用的属性值。类只是对象集合的一组常见定义。我们应该将类​​视为定义,而不是实际的东西。

类的实例"对象"是具有实际属性值并执行方法功能的实际事物。

我们不要在类之间传递变量。我们在实例之间传递变量。实际上,仅实例变量很重要。 [是的,有类变量,但是它们是相当专业的,并且常常令人困惑,最好避免。]

创建对象(类的实例)时

b= BasicInfoPage(...)

那么," b.intelligence"是" BasicInfoPage"的" b"实例的智能值。

一个真正常见的事情是

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

现在,在MOS方法中,我们可以说" self.basicInfo.intelligence",因为MOS具有一个对象,该对象是可用于BasicInfoPage的对象。

生成MOS时,会为其提供应使用的BasicInfoPage实例。

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

现在,对象" m"可以检查" someBasicInfoPage.intelligence"

向导本身的每个页面实际上都不应该是我们所收集信息的容器。

阅读Model-View-Control设计模式。页面包含设计的"查看"和"控制"部分。但是,它们不是数据模型。

如果我们有一个由页面"构建"的单独对象,那么我们会更快乐。每个页面将设置该基础模型对象的某些属性。然后,页面彼此独立,因为页面都获取并设置了该基础模型对象的值。

由于我们正在构建角色,因此我们将拥有一些类似的课程

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

然后,只需为各种Wizard实例提供基础的Character对象,即可放置和获取值。

我的问题确实是类与实例的混淆。我试图通过类来做所有事情,而无需创建实际实例。另外,我强迫" BasicInfoPage"类做太多的工作。

最终,我创建了一个新类(BaseAttribs)来容纳我需要的所有变量。然后,当我运行向导并将该实例作为参数传递给需要它的类时,便在该类的实例中创建它,如下所示:

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

然后,我使用S.Lott提供的信息,并在每个类中创建了单独的实例(如果这样的话)。每个类都访问相同的变量。

据我所知,一切正常。谢谢。