![](/img/trans.png)
[英]__str__(self) function not working for printing objects in Python
[英]Printing individual list objects within __str__ using .format(**self.__dict__)
我正在为游戏角色对象打印一个统计块。 在上一个问题中,向我展示了一种在__str__
函数中使用显示对象数据的方法,如下__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变量有关。 这些项目在“角色”对象中定义为单个项目列表: weapon=[]
,依此类推。 使用上述方法将返回列表对象,而不是列表对象所包含的没有[]
的对象。 我评价者看到一个空白的" "
字符串或列表中的包含的对象(如果存在),而不是[]
NAME: Bones
XP: 0
HP: 100
SP: 100
STR: 14
DEX: 19
WEAPON: []
SPELL: []
ITEM: []
AURA: []
我尝试了许多实验,包括在定义current_weapon = weapon[0]
之后,用{current_weapon}
替换{weapon}
引用,如果列表对象为空,则该方法将不起作用。 那只是IndexError: list index out of range
错误IndexError: list index out of range
。 我可以在对象实例化时生成项目,但由于self.item
会是一个空列表容器,因此无法正常工作。
我可以传播带有" "
对象的列表,但随后必须用替换项目将它们弄乱,并保持跟踪状态,这看起来非常微不足道,而且可能很麻烦。
我似乎似乎无法用一种优雅的方式来按照目前的设计在上述__str__
返回中打印列表对象。 我仍在学习Python,并且想相信我可以在此return
字符串后面添加一个简单的附加内容来完成此操作。
另一种选择是使用字符串格式化的功能来检查所传入内容的属性,以及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())
您可以只创建字典的本地副本,并在将其传递给格式之前修改所需的值:
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
所做的self.status
。 现在,您只是在修改临时副本。
即使不是那么简单,您也可以通过简单的方法来完成。 您可以修改字符串格式以容纳整个对象并利用属性的功能,这具有不创建字典副本的优点,这对于大型对象而言可能很昂贵。
我将给您一个示例,该示例应与您的需求相近:
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__,则只会看到值c和d 。
这就是为什么我将整个对象传递给format函数并访问其属性,而不是将其传递给对象字典。
如果您不喜欢0.c_str
表示法,则可以以不同的方式对其进行转义,例如,使其与通常的表示法保持接近:
"{self.c_str}".format(self=self)
要么
"{foo.c_str}".format(foo=self)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.