0

ゲームキャラクターオブジェクトの統計ブロックを印刷しています。__str__前の質問で、次のような関数を使用してオブジェクトデータを表示する方法を示しました。

def __str__(self):
    if self.poisoned is True:
        status = "[POISONED]"
    else:
        status = ""
    self.status = status
    return ('NAME: {name} {status}\n' \
            'XP:   {xp}\n' \
            'HP:   {hit_points}\n' \
            'SP:   {spell_points}\n' \
            'STR:  {strength}\n' \
            'DEX:  {dexterity}\n' \
            'WEAPON: {weapon}\n' \
            'SPELL:  {spell}\n' \
            'ITEM:   {item}\n' \
            'AURA:   {aura}\n' \
            ).format(**self.__dict__)

私が解決したい問題は、WEAPON、SPELL、ITEM、およびAURA変数に関係しています。これらのアイテムは、Characterオブジェクトで単一のアイテムリストとして定義されますweapon=[]。上記のメソッドを使用すると、リストオブジェクトが含まれているオブジェクトではなく、リストオブジェクトが返されます[]。空白の" "文字列またはリストに含まれているオブジェクトが存在し、存在しない場合は、評価者に表示されます[]

NAME: Bones 
XP:   0
HP:   100
SP:   100
STR:  14
DEX:  19
WEAPON:   []
SPELL:    []
ITEM:     []
AURA:     []

リストオブジェクトが空の場合に機能しないものを定義した後、{weapon}参照を置き換えるなど、いくつかの実験を試みました。それはただのエラーです。オブジェクトのインスタンス化でアイテムを生成することはできますが、空のリストコンテナの場合とは異なり、機能しません。{current_weapon}current_weapon = weapon[0]IndexError: list index out of rangeself.item

リストを" "オブジェクトとともに伝播することはできますが、それらを置換アイテムと組み合わせて、非常にエレガントでなく、面倒な可能性があるように見えるこれを追跡する必要があります。

__str__現在設計されているように、上記のリターンでリストオブジェクトを印刷するためのエレガントな方法に頭を悩ませているようには思えません。私はまだPythonを学んでおり、これを行うためにこのreturn文字列に追加できる簡単な追加があると信じたいと思います。

4

3 に答える 3

2

もう 1 つのオプションは、文字列フォーマットの機能を使用して、渡されたものの属性をチェックし、それselfがメソッド内のローカル変数であるという事実を確認することです。

def __str__(self):
    status = '[POISONED]' if self.poisoned else ''
    weapon = self.weapon[0] if self.weapon else ''
    spell = self.spell[0] if self.spell else ''
    item = self.item[0] if self.item else ''
    aura = self.aura[0] if self.aura else ''
    return ('NAME: {self.name} {status}\n'
            'XP:   {self.xp}\n'
            'HP:   {self.hit_points}\n'
            'SP:   {self.spell_points}\n'
            'STR:  {self.strength}\n'
            'DEX:  {self.dexterity}\n'
            'WEAPON: {weapon}\n'
            'SPELL:  {spell}\n'
            'ITEM:   {item}\n'
            'AURA:   {aura}\n'
            ).format(**locals())
于 2012-11-28T02:30:01.330 に答える
1

それほど些細なことではなくても、簡単な方法でそれを行うことができます。文字列形式を変更して、オブジェクト全体を取得し、プロパティの能力を活用できます。これには、辞書のコピーを作成しないという利点があり、大きなオブジェクトにはコストがかかる可能性があります。

必要なものに近いはずの例を示します。

class A(object):
    def __init__(self):
        # one full list and one empty one
        self.c = [1,2,3]
        self.d = []

    #these two preperties create a string versione when requeste
    c_str = property(lambda self: ", ".join(str(i) for i in self.c))
    d_str = property(lambda self: ", ".join(str(i) for i in self.d))

    def __str__(self):
        #you have to use the dotted version because properties are not visibles 
        # from the dict attribute
        string = "c = {0.c_str} \nd = {0.d_str}"
        return string.format(self)
a = A()
print str(a)
# c = 1, 2, 3 
# d = 

ある種のゲームプロパティをプログラミングしている場合、それらを使用して関数ではなく属性として複雑な値を取得し、よりクリーンなコードを作成できるため、大きな命の恩人になる可能性があります。たとえば、値が正である場合など、値の挿入のチェックを実装することもできます。

編集:

0.c_str代わりに使用しているのはなぜc_strですか?これは、プロパティが特別なオブジェクトであり、ドット表記()を使用してアクセスした場合にのみ呼び出されるためですself.c_str。それらはオブジェクト__dict__に存在しないため、使用できません。__dict__を印刷しようとすると、値cdのみが表示されます。

そのため、オブジェクトディクショナリを渡す代わりに、オブジェクト全体をformat関数に渡し、その属性にアクセスしました。

表記が気に入らない場合は、0.c_str別の方法でエスケープできます。たとえば、通常の表記に近づけることができます。

"{self.c_str}".format(self=self)

また

"{foo.c_str}".format(foo=self)
于 2012-11-28T01:56:45.880 に答える
1

dict のローカル コピーを作成し、必要な値を変更してから、それをフォーマットに渡すことができます。

def __str__(self):
    local_data = self.__dict__.copy()

    local_data['status'] = "[POISONED]" if self.poisoned else ""

    local_data['weapon'] = " " if not self.weapon else ','.join(self.weapon)

    return ('NAME: {name} {status}\n' \
            'XP:   {xp}\n' \
            'HP:   {hit_points}\n' \
            'SP:   {spell_points}\n' \
            'STR:  {strength}\n' \
            'DEX:  {dexterity}\n' \
            'WEAPON: {weapon}\n' \
            'SPELL:  {spell}\n' \
            'ITEM:   {item}\n' \
            'AURA:   {aura}\n' \
            ).format(**local_data)

あなたがあなたのself.status. これで、一時コピーを変更するだけです。

于 2012-11-28T01:46:04.820 に答える