У меня есть класс под названием «Movable Piece». Конечно, я хочу, чтобы все экземпляры этого класса двигались. Для этого я думал, что другой класс под названием «Движение» будет приятным и многоразовым, если мне понадобится другой материал для перемещения. Кроме того, мне очень нравится, как выглядит код my_piece.move.up
.Динамически создавать методы для экземпляра в Python
Проблема возникает, когда я понимаю, что мне нужно динамически пытаться установить методы для экземпляра класса Movements, созданного Piece, поскольку функции, которые перемещают кусок, также могут быть определены пользователем. Как я могу это достичь? Я думаю, что код прояснит, что я хочу делать.
class MovablePiece(Piece):
class Movements:
def __init__(self, piece, movement_functions=None):
if movement_functions is None:
self.__default_movements(piece)
else:
self.__set_movements(movement_functions)
def __default_movements(self, piece):
def up(): return piece.move(piece.surroundings[Direction.UP])
def right(): return piece.move(piece.surroundings[Direction.RIGHT])
def down(): return piece.move(piece.surroundings[Direction.DOWN])
def left(): return piece.move(piece.surroundings[Direction.LEFT])
self.__set_movements([up, right, down, left])
def __set_movements(self, movement_functions):
for movement_function in movement_functions:
setattr(self, movement_function.__name__, movement_function)
def __init__(self, letter, name, movements=None, walkable=False):
Piece.__init__(self, letter, name, walkable)
self.move = MovablePiece.Movements()
Это, конечно, не будет работать: SetAttr пытается установить функцию как атрибут, который я не думаю, что имеет много смысла, но вы получите суть.
Это ошибка, когда я пытаюсь сделать my_piece.move.right
:
Traceback (most recent call last):
File "main.py", line 45, in <module>
screen.show()
File "/home/joaquin/Documents/escape/ludema/screen.py", line 12, in show
function()
File "main.py", line 35, in control_bruma
mappings[action]()
File "/home/joaquin/Documents/escape/ludema/pieces.py", line 78, in right
def right(): return piece.move(piece.surroundings[Direction.RIGHT])
TypeError: 'Movements' object is not callable
Аналогичная проблема, если я заставляю методы, чтобы быть staticmethods (как они фактически не требуют «я»):
Traceback (most recent call last):
File "main.py", line 45, in <module>
screen.show()
File "/home/joaquin/Documents/escape/ludema/screen.py", line 12, in show
function()
File "main.py", line 35, in control_bruma
mappings[action]()
TypeError: 'staticmethod' object is not callable
'setattr()' должно работать нормально. Проблема может заключаться в том, что функции не определены для принятия первого аргумента 'self', поэтому они не являются надлежащими методами. – martineau
Это не так. Я приложу ошибку, полученную трассировкой. – joaquinlpereyra
@martineau Я добавил трассировку для тех случаев, когда я пытаюсь сделать их staticmethods, которые вы не без параметров легко :) – joaquinlpereyra