实例没有属性“__len__”
instance has no attribute '__len__'
这将是一个简单的问题,因此您不会花太多时间向我解释,但它会帮助我(可能还有其他人)了解一些关于 类 和方法以及Python.
我的代码想要表示一个棋盘游戏,在这个级别只是在一个连续有 N 个孔的棋盘上,它可以容纳编号从 0 到 N-1(随机顺序)的弹珠。
class MarblesBoard:
'''define the board game'''
def __init__(self, Board):
self._Board = Board
self._n = len(Board)
'''first type of move available: switch the first two marbles'''
def switch(Board):
Board[0], Board[1] = Board[1], Board[0]
return Board
'''second type of move available: move all the marbles by 1 space to the left'''
def rotate():
temp = Board[0]
for i in range (0, n-1):
Board[i] = Board[i+1]
Board[n-1] = temp
return Board
'''print the state'''
def __repr__(Board):
for i in range(0, len(Board)):
print self[i],
'''rest to be developed when this works'''
现在,我测试显示棋盘和移动弹珠。所以我让
First = MarblesBoard([1,2,3,4])
First.rotate
并且只得到
<repr(<instancemethod at 0x104230410>) failed: AttributeError: MarblesBoard instance has no attribute '__len__'>
我知道已经有关于此错误消息的类似问题。
AttributeError: Entry instance has no attribute '__len__'
我还是不明白为什么我的代码中会出现同样的错误。你介意解释一下(一般来说)属性“len”是什么时候建立的,并且可能会建议如何在这段代码中完成它?
当你这样做时:
First = MarblesBoard([1,2,3,4])
First.rotate
__repr__
被调用,因此对象的表示可以在您的终端上回显。这是你的(请注意,打印在其中是错误的,你应该只是 return 字符串,但更正它超出了这个范围。):
def __repr__(Board):
for i in range(0, len(Board)):
print self[i],
你打电话给len(Board)
。这个参数,Board
实际上是对象的实例。而是使用 self
是 Pythonic。您还没有为 len
定义一个 __len__
函数来调用这个对象,因此您得到了您看到的错误。
这是我要进行的一些编辑的示例。首先继承自对象:
class MarblesBoard(object):
'''define the board game'''
接下来,我们只将class个名字大写:
def __init__(self, board):
self._board = board
self._n = len(board)
最后,文档字符串位于函数名称和参数下方:
def switch(self):
'''first type of move available: switch the first two marbles'''
self.board[0], self.board[1] = self.board[1], self.board[0]
return self.board
def __init__(self, Board):
self._Board = Board
self._n = len(Board)
'''first type of move available: switch the first two marbles'''
def switch(Board):
Board[0], Board[1] = Board[1], Board[0]
return Board
您似乎期望 switch
方法中的 Board
与 __init__
中的 Board
相同 - 但事实并非如此。任何方法的第一个参数是您正在使用的实例(因此,MarblesBoard
的实例,当您期望它是一个列表时) - 您给它的名称不会影响它,但它是按照惯例(正如您在 __init__
中正确完成的那样)将其称为 self
。
__init__
中的Board
是你实际传入的参数——一个列表。要以其他方法取回它,您需要将它附加到 self
- 您已经这样做了,它称为 self._Board
。与任何变量名称或函数参数一样,您选择的名称不会影响功能,但是 - 同样 - 有约定并且将其称为 self._board
(全部小写)会更常见。所以,你可以将上面两个方法重写为:
def __init__(self, board):
self._board = board
self._n = len(Board)
'''first type of move available: switch the first two marbles'''
def switch(self):
self._board[0], self._board[1] = self._board[1], self._board[0]
(请注意,您可能 不想 想要 return 来自 switch
的任何内容,因为它改变了 self
的状态)。
这就把我们带到了问题的核心。 Python 正在隐式调用 __repr__
方法,您已将其定义为:
def __repr__(Board):
for i in range(0, len(Board)):
print self[i],
同样的事情正在发生:你期望 Board
是一个列表,而它是一个 MarblesBoard
。调用 len(Board)
然后尝试调用不存在的 MarblesBoard.__len__
。您还尝试过调用 self[i]
如果之前没有调用,这也会是一个错误(因为它调用了另一种魔术方法,MarblesBoard.__getitem__
,您也没有定义) .一次解决这两个问题的方法是完全按照我们上面所做的并通过 MarblesBoard
实例进入列表:
def __repr__(self):
for i in range(0, len(self._board)):
print self._board[i]
会起作用的。但是,请注意,此公式仍然不是很 Pythonic - 一旦您的代码起作用,您可能需要考虑将其发布到 codereview.SE.
这将是一个简单的问题,因此您不会花太多时间向我解释,但它会帮助我(可能还有其他人)了解一些关于 类 和方法以及Python.
我的代码想要表示一个棋盘游戏,在这个级别只是在一个连续有 N 个孔的棋盘上,它可以容纳编号从 0 到 N-1(随机顺序)的弹珠。
class MarblesBoard:
'''define the board game'''
def __init__(self, Board):
self._Board = Board
self._n = len(Board)
'''first type of move available: switch the first two marbles'''
def switch(Board):
Board[0], Board[1] = Board[1], Board[0]
return Board
'''second type of move available: move all the marbles by 1 space to the left'''
def rotate():
temp = Board[0]
for i in range (0, n-1):
Board[i] = Board[i+1]
Board[n-1] = temp
return Board
'''print the state'''
def __repr__(Board):
for i in range(0, len(Board)):
print self[i],
'''rest to be developed when this works'''
现在,我测试显示棋盘和移动弹珠。所以我让
First = MarblesBoard([1,2,3,4])
First.rotate
并且只得到
<repr(<instancemethod at 0x104230410>) failed: AttributeError: MarblesBoard instance has no attribute '__len__'>
我知道已经有关于此错误消息的类似问题。 AttributeError: Entry instance has no attribute '__len__'
我还是不明白为什么我的代码中会出现同样的错误。你介意解释一下(一般来说)属性“len”是什么时候建立的,并且可能会建议如何在这段代码中完成它?
当你这样做时:
First = MarblesBoard([1,2,3,4])
First.rotate
__repr__
被调用,因此对象的表示可以在您的终端上回显。这是你的(请注意,打印在其中是错误的,你应该只是 return 字符串,但更正它超出了这个范围。):
def __repr__(Board):
for i in range(0, len(Board)):
print self[i],
你打电话给len(Board)
。这个参数,Board
实际上是对象的实例。而是使用 self
是 Pythonic。您还没有为 len
定义一个 __len__
函数来调用这个对象,因此您得到了您看到的错误。
这是我要进行的一些编辑的示例。首先继承自对象:
class MarblesBoard(object):
'''define the board game'''
接下来,我们只将class个名字大写:
def __init__(self, board):
self._board = board
self._n = len(board)
最后,文档字符串位于函数名称和参数下方:
def switch(self):
'''first type of move available: switch the first two marbles'''
self.board[0], self.board[1] = self.board[1], self.board[0]
return self.board
def __init__(self, Board):
self._Board = Board
self._n = len(Board)
'''first type of move available: switch the first two marbles'''
def switch(Board):
Board[0], Board[1] = Board[1], Board[0]
return Board
您似乎期望 switch
方法中的 Board
与 __init__
中的 Board
相同 - 但事实并非如此。任何方法的第一个参数是您正在使用的实例(因此,MarblesBoard
的实例,当您期望它是一个列表时) - 您给它的名称不会影响它,但它是按照惯例(正如您在 __init__
中正确完成的那样)将其称为 self
。
__init__
中的Board
是你实际传入的参数——一个列表。要以其他方法取回它,您需要将它附加到 self
- 您已经这样做了,它称为 self._Board
。与任何变量名称或函数参数一样,您选择的名称不会影响功能,但是 - 同样 - 有约定并且将其称为 self._board
(全部小写)会更常见。所以,你可以将上面两个方法重写为:
def __init__(self, board):
self._board = board
self._n = len(Board)
'''first type of move available: switch the first two marbles'''
def switch(self):
self._board[0], self._board[1] = self._board[1], self._board[0]
(请注意,您可能 不想 想要 return 来自 switch
的任何内容,因为它改变了 self
的状态)。
这就把我们带到了问题的核心。 Python 正在隐式调用 __repr__
方法,您已将其定义为:
def __repr__(Board):
for i in range(0, len(Board)):
print self[i],
同样的事情正在发生:你期望 Board
是一个列表,而它是一个 MarblesBoard
。调用 len(Board)
然后尝试调用不存在的 MarblesBoard.__len__
。您还尝试过调用 self[i]
如果之前没有调用,这也会是一个错误(因为它调用了另一种魔术方法,MarblesBoard.__getitem__
,您也没有定义) .一次解决这两个问题的方法是完全按照我们上面所做的并通过 MarblesBoard
实例进入列表:
def __repr__(self):
for i in range(0, len(self._board)):
print self._board[i]
会起作用的。但是,请注意,此公式仍然不是很 Pythonic - 一旦您的代码起作用,您可能需要考虑将其发布到 codereview.SE.