Передача 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» 1980-х годов.
Я использую wxPython для создания мастера;родительским классом моих классов является Wizard из wxPython.Этот мастер проведет пользователя через процесс создания персонажа, поэтому страница «Основная информация» (класс BasicInfoPage) позволяет пользователю указать имя персонажа и «проверить» его атрибуты.Вот откуда возникает «саморазум».
Я пытаюсь использовать созданные ею атрибуты для дальнейшей страницы в мастере, где пользователь выбирает специальность персонажа.Доступные специальности зависят от атрибутов, которыми обладает персонаж, например.если интеллект достаточно высок, персонаж может быть аналитиком Intel.
Прошло несколько лет с тех пор, как я программировал, особенно с идеями ООП.Вот почему я не понимаю, как создать глобальную переменную с классами и методами.
Решение
Возможно, вы перепутали «Класс» и «Экземпляр».Из вашего примера это неясно, поэтому я предполагаю, что вы используете множество определений классов и не имеете соответствующих экземпляров объектов этих классов.
Классы на самом деле не имеют полезных значений атрибутов.Класс — это просто общий набор определений для коллекции объектов.Вы должны думать о классах как об определениях, а не как о реальных вещах.
Экземпляры классов, «объекты», — это реальные вещи, имеющие фактические значения атрибутов и выполняющие функции методов.
Вы не передаете переменные между занятия.Вы передаете переменные между случаи.На практике имеют значение только переменные экземпляра.[Да, существуют переменные класса, но они довольно специализированные и часто сбивают с толку, их лучше избегать.]
Когда вы создаете объект (экземпляр класса)
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
Другие советы
Каждая страница мастера сама по себе не должна быть контейнером для собираемой вами информации.
Прочтите о Модель-Вид-Управление шаблон дизайна.На ваших страницах есть части дизайна «Просмотр» и «Управление».Однако они не являются моделью данных.
Вы будете счастливее, если у вас будет отдельный объект, «построенный» страницами.На каждой странице будут установлены некоторые атрибуты этого базового объекта модели.Тогда страницы независимы друг от друга, поскольку все страницы получают и устанавливают значения этого базового объекта модели.
Поскольку вы создаете персонажа, у вас будет такой класс.
class Character( object ):
def __init__( self ):
self.intelligence= 10
<default values for all attributes.>
Тогда вашим различным экземплярам Wizard просто нужно будет предоставить базовый объект «Символ» в качестве места для ввода и получения значений.
Моя проблема действительно заключалась в путанице классов и классов.экземпляры.Я пытался сделать все с помощью классов, даже не создавая реальный экземпляр.Кроме того, я заставлял класс BasicInfoPage выполнять слишком много работы.
В конечном итоге я создал новый класс (Базовые атрибуты), чтобы хранить все нужные мне переменные.Затем я создал экземпляр этого класса при запуске мастера и передал этот экземпляр в качестве аргумента классам, которым он нужен, как показано ниже:
#---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)
Затем я использовал информацию, предоставленную С.Лоттом, и создал отдельные экземпляры (если это так называется) внутри каждого класса;однако каждый класс обращается к одним и тем же переменным.
Все работает, насколько я могу судить.Спасибо.
Все, что вам нужно, это ссылка.На самом деле это не простая проблема, для которой я могу дать какое-то однострочное решение (кроме простой уродливой глобальной проблемы, которая, вероятно, сломает что-то еще), а проблема структуры программы.Вы не получите волшебным образом доступ к переменной, созданной в другом экземпляре другого класса.Вам придется либо передать ссылку на интеллект в 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)
Если я Вас правильно понял, то ответ такой:Вы не можете.
интеллект должен быть атрибутом WizardPageSimple, если вы хотите, чтобы оба класса его наследовали.
В зависимости от вашей ситуации вы можете попытаться извлечь интеллект и связанные атрибуты в другой базовый класс.Тогда вы можете наследовать от обоих:
class MOS(wiz.WizardPageSimple, wiz.IntelligenceAttributes): # Or something like that.
В таком случае вы должен используйте кооперативный супер.На самом деле, вы уже должны его использовать.Вместо того, чтобы звонить
wiz.WizardPageSimple.__init__(self, parent)
вызов
super(MOS, self).__init__(self, parent)