クラス間での 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 クラスへの "Intelligence" 変数の使用方法がわからないことです。インターネット上でさまざまなことを試してみましたが、何もうまくいかないようです。私には何が欠けているのでしょうか?
編集 この記事を投稿してから、うまく説明できていないことに気づきました。1980 年代の Twilight 2000 RPG のコンピューター バージョンを作成しようとしています。
私は wxPython を使用してウィザードを作成しています。私のクラスの親クラスは、wxPython のウィザードです。このウィザードはユーザーにキャラクターの作成手順を案内するため、基本情報ページ (クラス BasicInfoPage) でユーザーはキャラクターの名前とキャラクターの属性の「ロール」を指定できます。そこから「自己知性」が生まれます。
私は、ユーザーがキャラクターの専門分野を選択するウィザードのさらに先のページで、彼女が作成した属性を使用しようとしています。利用可能な特技は、キャラクターが持つ属性によって異なります。知能が十分に高ければ、キャラクターは Intel Analyst になることができます。
特に OOP のアイデアを使ってプログラミングするのは数年ぶりです。そのため、クラスとメソッドを使用して本質的にグローバル変数であるものを作成する方法がわかりません。
解決
「クラス」と「インスタンス」を混同している可能性があります。あなたの例からは明らかではないので、多くのクラス定義を使用していて、それらのクラスの適切なオブジェクトインスタンスがないのだと推測します。
実際にはクラスには使用可能な属性値がありません。クラスは、オブジェクトのコレクションに対する共通の定義セットにすぎません。クラスは実際のものではなく、定義として考える必要があります。
クラスのインスタンスである「オブジェクト」は、実際の属性値を持ち、メソッド関数を実行する実際のものです。
変数を渡しません クラス. 。間で変数を渡します インスタンス. 。実際問題として、重要なのはインスタンス変数のみです。[はい、クラス変数はありますが、これはかなり特殊で、混乱を招くことが多いため、避けるのが最善です。]
オブジェクト(クラスのインスタンス)を作成するとき
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 を構築するときは、MOS が使用する BasicInfoPage のインスタンスを MOS に提供します。
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」クラスにあまりにも多くの作業を強制していました。
最終的に、新しいクラスを作成しました(基本属性) 必要なすべての変数を保持します。次に、以下に示すように、ウィザードの実行時にそのクラスのインスタンスを作成し、そのインスタンスを必要なクラスに引数として渡します。
#---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 行で解決できるような単純な問題ではありません (おそらく他の何かを壊してしまうような単純で醜いグローバルを除く) が、プログラム構造の問題です。別のクラスの別のインスタンスで作成された変数に魔法のようにアクセスできるわけではありません。インテリジェンス参照を 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)
私の理解が正しければ、答えは次のようになります。あなたはできません。
両方のクラスに Intelligence を継承させたい場合は、WizardPageSimple の属性にする必要があります。
状況に応じて、インテリジェンスと関連する属性を別の基本クラスに抽出しようとすることもあります。次に、両方から継承できます。
class MOS(wiz.WizardPageSimple, wiz.IntelligenceAttributes): # Or something like that.
その場合、あなたは しなければならない 生協スーパーを利用する。実際、すでに使用しているはずです。電話をかける代わりに
wiz.WizardPageSimple.__init__(self, parent)
電話
super(MOS, self).__init__(self, parent)