Переменная, передающая Python между классами

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

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

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» 80-х годов.

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

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

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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
22 855
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

интеллект должен быть атрибутом 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 - это значение интеллекта для экземпляра bBasicInfoPage.

Действительно обычная вещь

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.

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

Прочтите о шаблоне проектирования Модель-Просмотр-Контроль. На ваших страницах есть части дизайна "Просмотр" и "Управление". Однако это не модель данных.

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

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

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, и создал отдельные экземпляры (если они так назывались) внутри каждого класса; однако каждый класс обращается к одним и тем же переменным.

Насколько я могу судить, все работает. Спасибо.

Другие вопросы по теме