为什么在我的代码中 python 在某些情况下打印内存位置而不是 class.name 而在其他情况下不打印?

Why does python print memory location rather than class.name in some cases but not others in my code?

我的代码有一个数学函数,它遍历县 class 对象的列表,returns 具有最大选民投票率的县以及元组中的投票率。

代码在这里:

class County :
  def __init__(self, init_name, init_population, init_voters):
    self.name = init_name
    self.population = init_population
    self.voters = init_voters
    
def highest_turnout(data) :
  max_turnout_county = data[0]
  max_turnout = (data[0].voters / data[0].population)
  for i in range(0,6):
    if (data[i].voters / data[i].population) > max_turnout:
      max_turnout_county = data[i].name
      max_turnout = (data[i].voters / data[i].population)

  return (max_turnout_county, max_turnout)


allegheny = County("allegheny", 1000490, 645469)
philadelphia = County("philadelphia", 1134081, 539069)
montgomery = County("montgomery", 568952, 399591)
lancaster = County("lancaster", 345367, 230278)
delaware = County("delaware", 414031, 284538)
chester = County("chester", 319919, 230823)
bucks = County("bucks", 444149, 319816)
data = [allegheny, philadelphia, montgomery, lancaster, delaware, chester, bucks]  

result = highest_turnout(data) 
print(result) # prints the output of the function

在其当前状态下,它将return 所需的输出。 ('chester', 0.7215045058280377)

但是,如果我更改投票率最高的县,例如,如果我将阿勒格尼选民从 645469 更改为 1000480,那么阿勒格尼现在是投票率最高的县,则输出将不再 return 该县元组中的名称符合预期,而不是内存位置。

这里输出: (,0.9999900048976001)

为什么我的代码在第二种情况下输出内存位置而不是第一种情况,我该如何解决这个问题?

您的代码中存在错误。 在第一行中,您将整个县对象分配给 max_county_variable

max_turnout_county = data[0]

稍后,您仅分配属性名称:

 max_turnout_county = data[i].name

要修复,您只需将第一行更改为:

max_turnout_county = data[0].name

您使用参数 County 的实例初始化 max_turnout_county

max_turnout_county = data[0]

应该初始化为县的名称

max_turnout_county = data[0].name

或者,您可以将投票率 属性 添加到您的 County class:

class County :
  def __init__(self, init_name, init_population, init_voters):
    self.name = init_name
    self.population = init_population
    self.voters = init_voters

  @property
  def turnout(self):
     return self.voters / self.population

大大简化了您的函数:

def highest_turnout(data) :
  return max(data, key=lambda c: c.turnout)
  # Or, if you really want to return a tuple instead of
  # an instance of County,
  # c = max(data, key=lambda c: c.turnout)
  # return (c.name, c.turnout)
  

添加这个

 def __str__(self):
        return self.name

str method is used to show name of objects rather than memory location and it must be a string.

控制 class 的对象在打印时如何显示它们自己的是 __repr__ 的存在(或者,如果您想区分用于调试的内部表示与实际 printed-out, __str__) 方法。

默认的__repr__,但是,如果你不在你的class中写一个,就是class名字和记忆位置。

在您上面的代码片段中,当满足某些条件时,max_turnout_county 被分配 data[i].name- 即您的实例的名称,它是一个字符串。如果不满足该条件,则同一变量仍然分配给对象本身 data[0].

根据你想用这些对象做什么,最好的办法是为它们写一个合适的__repr__方法,不要只使用.name,而是实际的任何作业中的对象。对象 repr 甚至可以负责输出您关心的任何其他属性,因此无需在函数中保留两个状态变量,并返回一个元组:

class County :
  def __init__(self, init_name, init_population, init_voters):
    self.name = init_name
    self.population = init_population
    self.voters = init_voters
    
  # Bonus: yoru object can have a calculated property:
  @property
  def turnout(self):
      return self.voters/self.population
      
  def __repr__(self):
    return f"{self.name}, turnout: {(self.turnout * 100):.02f}"

def highest_turnout(data) :
  max_turnout_county = data[0]
  max_turnout = (data[0].voters / data[0].population)
  for i in range(0,6):
    if (data[i].turnout) > max_turnout:
      max_turnout_county = data[i]    # <- this would change
      max_turnout = (data[i].voters / data[i].population)

  return max_turnout_county


allegheny = County("allegheny", 1000490, 645469)
philadelphia = County("philadelphia", 1134081, 539069)
montgomery = County("montgomery", 568952, 399591)
lancaster = County("lancaster", 345367, 230278)
delaware = County("delaware", 414031, 284538)
chester = County("chester", 319919, 230823)
bucks = County("bucks", 444149, 319816)
data = [allegheny, philadelphia, montgomery, lancaster, delaware, chester, bucks]  

result = highest_turnout(data) 
print(result) # prints the output of the function

# as part of the bonus - you don't even need a function for that,
# as each object now "knows" its turnout, Python's built-in 
# "max" function can find your optimal county:
print(max(data, key=lambda c: c.turnout))