我遇到了一些关于函数,方法之间相互作用的问题,并且对如何利用内置函数__str__
有不确定性。
为了开始这个,我有一个名为vara的类,它看起来像:
class vara(object):
def __init__(self, kod, namn, pris, butikantal):
self.kod = kod
self.namn = namn
self.pris = pris
self.antal = butikantal
我有一个函数可以为vara klass创建一个对象列表,如下所示:
def mina_varor():
varor_fran_fil = open("varor.txt", "r")
varulista = []
for rad in varor_fran_fil:
varje_vara1 = rad
varje_vara2 = varje_vara1.split("/")
varorna = vara(varje_vara2[0], varje_vara2[1], varje_vara2[2], varje_vara2[3])
varulista.append(varorna)
return(varulista)
现在我希望能够通过输入对象的“kod”来访问此列表中的singel对象。但是我在列表中找不到任何“kod”。这看起来很奇怪,所以我尝试打印清单,并得到了:
[<__main__.vara object at 0x00000000031503C8>, <__main__.vara object at 0x00000000031507F0>, <__main__.vara object at 0x0000000003150710>, <__main__.vara object at 0x00000000031502B0>, <__main__.vara object at 0x00000000031505F8>, <__main__.vara object at 0x00000000031504E0>]
我查了一下,似乎python无法决定如何解释我的列表。我想我需要一个__str__
方法才能这样做,但是如果我希望它打印出类似的内容,我应该如何使__str__
方法看起来像:
Name: Hat
Price: 150
Quantity: 100
Code: 223
答案 0 :(得分:1)
并不是说Python无法解释您的列表,而是它不知道您希望如何显示它。
如果您想执行类似
的操作,请实施__str__
方法
print(varulista[0])
以下内容会为您提供类似于您对该列表条目的期望:
def __str__(self):
s = "Name: %s\n" % self.namn
s += "Price: %s\n" % self.pris
s += "Quantity:%s\n" % self.antal
s += "Code: %s\n" % self.kod
但是,如果您希望print(varulista)
有任何意义,那么您还必须实现__repr__
方法,因为varulista
是一个列表,当打印时,Python会查找__repr__
方法。
但话虽如此,__repr__
的想法是能够将其传递回eval()
并创建一个等效对象。所以你可以选择以下两种方式之一:
<强> 1。忽略__repr__()
/ eval()
互动
在这种情况下,只需实现__repr__()
即可。请记住,当它是您要打印的容器中的项目时,将调用此方法,因此将输出保持为单行可能会有所帮助。只要知道,除非您明确地表示__repr__()
输出中对象的状态,否则您将无法重新创建等效对象&#34;在路上&#34;使用eval()
。
<强> 2。 (首选方案,IMO)正确实施__repr__()
,如果您不喜欢它的外观,就不要打印容器。
如果输出
[Item{Name:"Hat",Price:150,Quantity:100,Code:223},Item{Name:"Shirt",Price:450,Quantity:10,Code:225}]
由于你必须如何实施__repr()__
而不打印容器,太不友好了。换句话说,不要使用
print(varulista)
但请改用
for item in varulista: print item
会调用您定义的__str__()
方法,这是人性化的方法。
编辑: @ bernie关于__str__
与__repr__
之间差异的a great answer by @AlexMartelli链接指向值得链接两次。
你说
现在我希望能够通过输入&#34; kod&#34;来访问此列表中的singel对象。对象。但我找不到任何&#34; kod&#34;在我的清单中。这看起来很奇怪,所以我尝试打印清单,并得到了:
这里有两个主要选项。 (1)使用键入项目代码的字典。 (2)使用列表理解在列表中搜索代码。我只会去展示(1),因为我认为这是一个更好的选择。
选项1:使用项目代码上键入的词典
考虑以下代码:
# Define a convenience function to add items to the dictionary
def add_item(d,i): d[i.kod] = i
# Create a new dictionary
items = {}
# Add items to dictionary
add_item(items, vara(223, "Hat", 150, 100))
add_item(items, vara(225, "Shirt", 450, 10))
您现在可以访问items
字典中的任何已定义项目,如下所示:
items[223] #<-- This is the "Hat" item
items[225] #<-- This is the "Shirt" item
答案 1 :(得分:0)
你可以这样覆盖__repr__
:
class vara():
def __init__(self, kod, namn, pris, butikantal):
self.kod = kod
self.namn = namn
self.pris = pris
self.antal = butikantal
def __repr__(self):
return 'Name: %s\nPrice: %s\nQuantity:%s\nCode: %s\n'\
% (self.namn, self.pris, self.antal, self.kod)
输出:
>>> print([vara('223', 'Hat', '150', '100'), vara('115', 'Bla', '154', '200')])
[Name: Hat
Price: 150
Quantity:100
Code: 223
, Name: Bla
Price: 154
Quantity:200
Code: 115
]
修改强>
但是正如@jedwards所解释的那样,覆盖__str__
的方法与我对__repr__
的覆盖方式相同,并且单独打印每个对象而不是打印整个列表。