函数和类,__str__的用法

时间:2013-04-05 15:58:53

标签: python string list class function

我遇到了一些关于函数,方法之间相互作用的问题,并且对如何利用内置函数__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

2 个答案:

答案 0 :(得分:1)

问题1:打印容器时未调用__str __()

并不是说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链接指向值得链接两次。


问题2:能够通过它的代码访问列表元素

你说

  

现在我希望能够通过输入&#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__的覆盖方式相同,并且单独打印每个对象而不是打印整个列表。