0

I'm trying to make a simple game which creates certain boards dependant on the values of a sequence. This is the variable:

nextCommand = "board" + str(sequence[sequenceIndex]) + "()"

How do I use the value of 'nextCommand' to run the function boardx()? (with x being a number)

blhsing
  • 91,368
  • 6
  • 71
  • 106
  • 1
    you can create a dictionary with your function names mapped to the functions – Chris_Rands Mar 09 '19 at 13:33
  • For some reason it has been marked as a duplicate to a completely unrelated topic. The correct way to address this and run what you need is to use `exec(nextCommand)` – BoobyTrap Mar 09 '19 at 13:57

1 Answers1

2

You can use the globals function to obtain a dict of the global namespace so that you call the function named after a string:

globals()[str(sequence[sequenceIndex])]()

Note, however, that the fact that these functions do things so similar that you can iterate through the function names with an index highly suggests that there is no need for these functions to be separate in the first place.

So instead of creating functions named after an index such as board0, board1, etc.:

def board0():
    print('OOXX')
def board1():
    print('XOXO')

you should consider making the index a parameter and making the function adopt different logics and/or data according to this parameter:

boards = [
    'OOXX',
    'XOXO'
]
def board(x):
    print(boards[x])
board(index)

On the other hand, if the logics of these functions do differ greatly, to the point that you would be using a lot of if statements with distinctly different logics based on the index, it does make sense to make these functions separate, in which case you can do what @Chris_Rands suggests in the comments, to store the function objects in a mapping list or dict, and call the function after retrieving the function object from the mapping according to the index instead:

def tough_board():
    print('OOXX')

def tame_board():
    print('XOXO')

boards = [tough_board, tame_board]
boards[index]()
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • 1
    This is almost never the best way to call a function, especially as advice to a beginner – Chris_Rands Mar 09 '19 at 13:31
  • 1
    That did it. Thanks. (Either way) – Jakub Slapek Mar 09 '19 at 13:32
  • Why would you even suggest globals as an answer for this? I have never had to use global parameters. – BoobyTrap Mar 09 '19 at 13:50
  • @BoobyTrap All modules, classes and functions you define at the module level are "global". You certainly have used them before. – blhsing Mar 09 '19 at 13:58
  • I know what a global parameter is. I use module parameters (i.e globals) as constants in a completely different constants file and import where needed. I would never write a constant global parameter in the same module and it shouldn't be suggested to do so. Suggesting to use global for something that is solved by `exec` is wrong. The whole purpose of global parameters is for constants, not for bad programming practices. – BoobyTrap Mar 09 '19 at 14:04
  • Calling `exec` is the worst possible solution. It introduces vulnerability to code injection attack and adds runtime-compilation overhead to your code. – blhsing Mar 09 '19 at 14:09
  • You're mixing up global variables with global functions. The OP is asking about global functions, which are certainly commonly used everywhere including the bulk of the standard library, and you have certainly used them before. – blhsing Mar 09 '19 at 14:10
  • 1
    Nope, for some reason I read it as if you suggested OP makes `nextCommand` global. `exec` however will not introduce a vulnerability seeing as OP seems to be getting the value from an existing list and not as input. If you edit your answer I can undo the downvote as it is my mistake. – BoobyTrap Mar 09 '19 at 14:30
  • 1
    No problem. I've updated my answer with a more rounded suggestion. Thanks. – blhsing Mar 09 '19 at 14:54