2016-04-28 13 views
2

私の簡略化.kvファイル:なぜ、 `` NoneType 'オブジェクトに.kvファイルの属性がありませんか?

<GameWorld>: 
    player: the_player 

    canvas: 
     Rectangle: 
      pos: 5, root.top - 25 
      size: self.player.health, 20 # error raised in this line 

    Player: 
     id: the_player 
     center: self.center 

マイ簡略化されたPythonファイル:

class Player(Widget): 
    health = NumericProperty(50) 

    def __init__(self, **kwargs): 
     super(Player, self).__init__(**kwargs) 
     self.health = 100 

class GameWorld(Widget): 
    player = ObjectProperty() 
    entities = ListProperty() 

    def __init__(self, **kwargs): 
     super(GameWorld, self).__init__(**kwargs) 
     self.entities.append(self.player) 

私が取得エラー:

AttributeError: 'NoneType' object has no attribute 'health' 

Kivyがself.playerNoneであると考えています。何が間違っているのか理解してください。

+0

IIRC新しいスタイルクラスを使用すると、self' 'を通じて、クラスのメンバへの参照を行うことはできません。 'GameWorld.player'を使用してください。またはおそらく '自己.__クラス__。プレーヤー '。 –

+0

私は[これ](http://stackoverflow.com/questions/10789296/attributeerror-nonetype-object-has-no-attribute-health)古い投稿あなたの問題に答えることを願っています。 – Spiderman

+0

@BrianCain私は同じことを考えて(そして、その効果に対する答えを掲示しましたが)シェルでテストすると、それが正しくないことが示されます。 –

答えて

1

canvas命令が評価されるとき、GameWorld.playerはまだNoneであり、デフォルトはObjectPropertyであり、したがってエラーです。

あなたは、このようなKVルールにNoneためのテストを追加した場合:

<GameWorld>: 
    player: the_player 
    canvas: 
     Rectangle: 
      pos: 5, root.top - 25 
      size: self.player is not None and self.player.health, 20 

エラーがスローされませんが、自動バインディングは実行されません。しかし、あなたがObjectPropertyの宣言にrebind=Trueを追加した場合:

class GameWorld(Widget): 
    player = ObjectProperty(rebind=True) 

これは正しく動作します。


残し少ないエレガントな代替ソリューションまで:あなたはあることの唯一の目的で、GameWorldに別のNumericPropertyを追加することができ、

class GameWorld(Widget): 
    player = ObjectProperty(Player()) 

をまたは:

あなたは定義でPlayerオブジェクトをインスタンス化できplayer.healthにバインドされていますが、わかりやすい値に初期化されています。

class GameWorld(Widget): 
    _player_health = NumericProperty(1) 

<GameWorld>: 
    player: the_player 
    _player_health: the_player.health 

    canvas: 
     Rectangle: 
      pos: 5, root.top - 25 
      size: self._player_health, 20 
+0

私は参照してください。プロパティが設定される前にキャンバス命令が実行される理由はありますか?それを変える方法はありますか? –

+0

@AvivCohn自動的にそれを行うためのより良い方法の編集を参照してください – zeeMonkeez

+0

新しいソリューションのおかげで、それは素晴らしいです。しかし、1つの質問:なぜ、「self.playerはNoneではなく、self.player.health'は動作しますか? Pythonシェルでは、booleanと評価されます。それは何をするためのものか? –

関連する問題