Python-переменная между классами - PullRequest
3 голосов
/ 22 сентября 2008

Я пытаюсь создать мастера генерации персонажей для игры. В одном классе я вычисляю атрибуты персонажа. В другом классе я показываю пользователю, какие специальности доступны в зависимости от атрибутов персонажа. Однако я не могу вспомнить, как передавать переменные между различными классами.

Вот пример того, что у меня есть:

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. Я пробовал несколько разных вещей со всего Интернета, но, похоже, ничего не работает. Чего мне не хватает?

Редактировать После публикации я понял, что не очень хорошо объяснил. Я пытаюсь создать компьютерную версию РПГ «Сумерки 2000» 1980-х годов.

Я использую wxPython для создания мастера; родительский класс моих классов - это Wizard из wxPython. Этот мастер проведет пользователя по созданию персонажа, поэтому страница «Основная информация» (класс BasicInfoPage) позволяет пользователю дать имя персонажа и «перекат» для атрибутов персонажа. Отсюда и «самоинтеллект».

Я пытаюсь использовать созданные ею атрибуты для дальнейшей страницы в мастере, где пользователь выбирает специальность персонажа. Доступные особенности зависят от атрибутов, которыми обладает персонаж, например, если интеллект достаточно высок, персонаж может быть Intel Anaylst.

Прошло несколько лет с тех пор, как я программировал, особенно с идеями ООП. Вот почему я запутался в том, как создать глобальную переменную с классами и методами.

Ответы [ 5 ]

6 голосов
/ 22 сентября 2008

Возможно, вы перепутали "Класс" и "Экземпляр". Это не ясно из вашего примера, поэтому я предполагаю, что вы используете много определений классов и не имеете соответствующих экземпляров объектов этих классов.

Классы не имеют реально используемых значений атрибутов. Класс - это просто общий набор определений для коллекции объектов. Вы должны думать о классах как об определениях, а не о реальных вещах.

Экземпляры классов, "объекты", являются фактическими вещами, которые имеют фактические значения атрибутов и выполняют функции метода.

Вы не передаете переменные среди классов . Вы передаете переменные среди экземпляров . На практике имеют значение только переменные экземпляра. [Да, есть переменные класса, но это довольно специализированная и часто запутанная вещь, которую лучше избегать.]

Когда вы создаете объект (экземпляр класса)

b= BasicInfoPage(...)

Тогда b.intelligence - это значение интеллекта для b экземпляра BasicInfoPage.

Действительно распространенная вещь

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

3 голосов
/ 22 сентября 2008

Каждая страница мастера - сама по себе - не должна быть контейнером для информации, которую вы собираете.

Ознакомьтесь с шаблоном проектирования Model-View-Control . Ваши страницы имеют элементы просмотра и контроля дизайна. Однако они не являются моделью данных.

Вы будете счастливее, если у вас есть отдельный объект, который "построен" из страниц. Каждая страница будет устанавливать некоторые атрибуты этого базового модельного объекта. Затем страницы не зависят друг от друга, поскольку все страницы получают и устанавливают значения этого базового объекта модели.

Поскольку вы создаете персонажа, у вас будет такой класс, как этот

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

Тогда вашим различным экземплярам Wizard нужно просто предоставить базовый объект Character в качестве места для размещения и получения значений.

2 голосов
/ 23 сентября 2008

Моей проблемой действительно было смешение классов и экземпляров. Я пытался сделать все через классы, даже не создавая фактический экземпляр. Кроме того, я заставлял класс 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 информацию и создал отдельные экземпляры (если так они называются) в каждом классе; хотя каждый класс обращается к одним и тем же переменным.

Все работает, насколько я могу судить. Благодаря.

1 голос
/ 22 сентября 2008

Все, что вам нужно, это ссылка. На самом деле это не простая проблема, которую я могу дать для однострочного решения (кроме простого уродливого глобала, который, вероятно, сломал бы что-то другое), а одна из структур программы. Вы волшебным образом не получаете доступ к переменной, которая была создана в другом экземпляре другого класса. Вы должны либо предоставить интеллектуальную ссылку на 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)
0 голосов
/ 22 сентября 2008

Если я вас правильно понял, то ответ: вы не можете.

интеллект должен быть атрибутом WizardPageSimple, если вы хотите, чтобы оба класса его унаследовали.

В зависимости от вашей ситуации вы можете попытаться извлечь интеллект и связанные атрибуты в другой базовый класс. Тогда вы можете наследовать от обоих:

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

В этом случае вы должны использовать кооперативный супер. На самом деле, вы должны уже использовать его. Вместо того, чтобы звонить

wiz.WizardPageSimple.__init__(self, parent)

вызов

super(MOS, self).__init__(self, parent)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...