Я пытаюсь создать мастера создания персонажей для игры. В одном классе я вычисляю атрибуты персонажа. В другом классе я показываю пользователю, какие особенности доступны в зависимости от атрибутов персонажа. Однако я не могу вспомнить, как передавать переменные между разными классами.
Вот пример того, что у меня есть:
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.
Прошло несколько лет с тех пор, как я программировал, особенно с идеями ООП. Вот почему я не понимаю, как создать глобальную переменную с классами и методами.






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