I have a class called 'Movable Piece'. Of course, I want every instance of this class to move. For that, I thought another class called 'Movement' would be nice, and reusable in case I need other stuff to move. Besides, I quite like how my_piece.move.up
looks in the code.
The problem comes when I realize I need to dynamically try to set methods for the instance of the Movements class instantiated by the Piece, as the functions that move the piece may as well be user-defined. How can I achieve this? I think the code will clarify what I want to do.
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()
This, of course, won't work: setattr is trying to set a function as an attribute, which I don't think makes much sense, but you get the gist of it.
This is the error when I try to do 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
Similar problem if I force the methods to be staticmethods (as they don't actually require 'self'):
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