2017-10-16 10 views
0

自動化されたジェネレータ用にデータ構造を設定しようとしています。私はロールプレイゲーム用に作成していますが、いくつかの特定の継承特有の問題があります。データ構造の抜粋です。特定のクラス継承の動作に問題がある

class data(): 
    def __init__(self): 
     self.races = Races() 
class Races(data): 
    def __init__(self): 
     self.humans = Humans() 
class Humans(Races): 
    def __init__(self): 
     self.Characteristics = { 
      'Brawn':2, 
      'Agility':2, 
      'Intellect':2, 
      'Cunning':2, 
      'Willpower':2, 
      'Presence':2 
      } 

構造にはまだ多くの部分がありますが、これは単なる下から上の概要です。私はそれが奇妙にインデントされていることも知っていますが、それは厳密にスタックオーバーフローです。

今、私はこのオブジェクトから2つの動作をしたいと思います。 data.races.humans.Characteristic['brawn'] を呼び出す形式として任意の特性を呼び出すことができます。私は、オブジェクトをインスタンス化している明らかにした後 (subclass for subclass in data.races.__subclasses__())

そして、あまりにものような発電機とサブクラスを反復処理することができます。

は今、私は構造を数回変更しようとしていると私はドット表記でそれを呼び出すことができますもその私はそれを得ることができますが、それは、完全に、より伝統的な構造にそれを分離することによりAttributeError: 'Races' object has no attribute '__subclasses__'

またはその逆を返しますが、私はドット表記法を呼び出すことはできません。これにより、すべてを整理して読みやすくすることが非常に難しくなります。

誰かが私が間違っていることを提案したり、問題に近づくためにもっとPythonの方法を提案できますか?

+1

注意してください - あなたが構成を望むように聞こえます、継承ではありません。人間はレースかもしれませんが、レースはデータではありません。 –

+0

人間がレースにリンクされ、レースはデータにリンクされていないのと全く同じ方法で作られていますか? それらが同じトップレベルオブジェクトに関連する理由は、データの種類が異なり、それをすべて自分のモジュールに入れて1つのオブジェクトをインスタンス化したいからです。 –

+0

@KirkReynolds 'data'は、' Race'が継承する単一のクラスではなく、 'race = [Human、Elf、Dwarf、...]'クラスのリストにすることができます。ポイント。実際には、どのようにデータをモデル化する必要があるかによって異なります。私は私の答えにちょっとした味を与えようとしましたが、あなたの質問はあまりに広範囲であり、ここでは役に立ちません。 – chepner

答えて

0

真ん中から始めましょう。おそらく、どのレースのキャラクターも同じ属性を持ち、それらの属性の値は異なるだけです。

class Race: 
    def __init__(self): 
     self.life = 100 # 100% healthy 

class Humanoid(Race): 
    def __init__(self): 
     super().__init__() 
     self.legs = 2 

class Insectoid(Race): 
    def __init__(self): 
     super().__init__() 
     self.legs = 8 

class Human(Humanoid): 
    def __init__(self): 
     super().__init__() 
     self.brawn = 2 
     self.agility = 2 
     self.intellect = 2 
     self.cunning = 2, 
     self.willpower = 2 
     self.presence = 2 

class Elf(Humanoid): 
    def __init__(self): 
     super.__init__() 
     self.brawn = 1 
     self.agility = 3 
     self.intellect = 3 
     self.cunning = 2 
     self.willpower = 3 
     self.presence = 1 

は今、任意の特定の文字が正しいクラスとしてインスタンス化されるだろう:前述ので

some_elf_1 = Elf() 
some_human_1 = Human() 
some_human_2 = Human() 

for character in [some_elf_1, some_human_1, some_human_2]: 
    print("Brawn: ", character.brawn) 

、各キャラクターの実際の型が何であるかは重要ではありません。 Race(またはRace自体のインスタンス)のサブクラスであることがわかっている限り、アクセス可能なbrawn属性を持ちます。

あなたdataクラスは、詳細がなければ実際には必要ないようです。

+0

私はそれを私が別のモジュールから一度に呼び出すことができるようにしていましたが、あなたのソリューションを見れば、それは私にとってはうまくいくようです。しかし、何百ものさまざまなレースが起こる可能性があります(これはスターウォーズです!)可能であれば、それらをすべて初期化しないでください。そのため、私はそれらをすべて1つのオブジェクトの下に置くことができると考えていました。必要に応じて特定のコールを呼び出すだけですが、オブジェクトを初期化するための定型的なコードを書かずに簡単に繰り返します。 –

+0

レースは関連していますか?私が示すものよりも複雑な階層を持つことができます。 'Race .__ init__'はどんなレースにも共通する初期化を行うことができ、中間クラスを作ることができます:王国、門、秩序、クラス、家族、属、種によって地球上の生命がどのように組織されるか考えてください。各門は王国を拡張するクラスであり、各序列は門などを拡張します。さらに、各祖母の '__init__'メソッドは、子の' __init__'メソッドから呼び出されます。 (答えに例を追加します)。 – chepner

0

答えが与えられている間、私は正しい軌道に乗っていましたが、私は必要なものを理解して、貧しい魂のために多くを投げかけています。

まず、私のジェネレータに何が間違っているかを認識しました。クラスオブジェクトではなく初期化されたオブジェクトを呼び出していました。オブジェクトにサブクラス attribがなく、私が読んだガイドのほとんどが誤って通知されました!

第2に、メタクラスを使用してオブジェクトからの反復動作を取得することは、すべての初期化されたサブクラスの辞書であるレジストリ属性を使用して簡単に達成できると考えました。

lass Races(data): 
def __init__(self): 
    self.humans = Humans() 
    self.droids = Droids() 
    self.twileks = Twileks() 
    self.registry = { 
      'humans':self.humans, 
      'droids':self.droids, 
      'twileks':self.twileks 
      } 

これにより、さまざまなレースの初期値を設定した後、特定の値を反復することができます。

ありがとうございました!