0

So I am not sure if this can be done at all, but was curious anyway. Let us suppose I have the following piece of code:

def statement1():
    # Do something

def statement2():
    # Do something

def statement3():
    # Do something

statement1()
statement2()
statement3()

Now, as you can see here, I have to execute all the above functions one after the other. They are also named in a similar fashion, so that made me wonder- is there a way to loop over function calls? I basically want to have something like a for loop which loops over 'statements', and I don't end up calling each one again and again with only a slight modification in the name.

A side note- I am new to the community so feel free to give me feedback on how to ask and comment on the answers, would go a long way in helping me.

Thanks in advance!

  • 1
    If you always call these three functions together, why not make them a single function? – Samwise May 31 '21 at 06:00
  • They perform different functionalities. I may need to call them at other places in the program as well, and combining all into one will take away the modularity of the functions. It is in this specific example that I need to call them one after the other. – Sarthak Saxena May 31 '21 at 06:06

9 Answers9

1

You can use globals() with fstring if the function name is always follow the specific pattern

def statement1():
    print("s1")

def statement2():
    print("s2")

def statement3():
    print("s3")

for i in range(3):
    globals()[f"statement{i+1}"]()

Output:

s1
s2
s3
deadshot
  • 8,881
  • 4
  • 20
  • 39
1

Try this:

def st1():
  return 'Hi 1'

def st2():
  return 'Hi 2'

def st3():
  return 'Hi 3'

list1 = [st1(), st2(), st3()]

for word in list1:
  print(word)
Dharman
  • 30,962
  • 25
  • 85
  • 135
0

Here is a way if you don't want to use globals:

import sys

def statement1():
    print(1)

def statement2():
    print(2)

def statement3():
    print(3)


for i in range(1, 4):
    f_name = 'statement{}'.format(i)
    getattr(sys.modules[__name__], f_name)()
Toni Sredanović
  • 2,280
  • 1
  • 11
  • 13
  • Thank you, this works well as well! However, is there a scenario where you would suggest this over globals() as an alternative? – Sarthak Saxena May 31 '21 at 05:49
  • Well, using `globals` is generally considered bad practice, not only in python but in any programming language. Here is a good read about it: https://stackoverflow.com/questions/19158339/why-are-global-variables-evil – Toni Sredanović May 31 '21 at 05:56
0

@deadshot has provided one option how it can be done. On the other hand, if you want to design it this way, I guess this is because you plan that the standard usage will require running all three functions in this exact order? In this case the more classic way would be to define a main function:

def statement1():
    # Do something

def statement2():
    # Do something

def statement3():
    # Do something

def main():
    statement1()
    statement2()
    statement3()

if __name__ == '__main__':
    main()

NotAName
  • 3,821
  • 2
  • 29
  • 44
  • True, I do want it in a specific order. However, what I was looking to avoid was the code repetition in typing 'statement..' while calling the functions. In that case, I believe that what @deadshot suggested works best. I'm using a main() function as well. Thanks for the help! – Sarthak Saxena May 31 '21 at 05:48
0

If the functions to similar things, you usually do this via arguments:

def statement(arg):
    # do something with arg

for i in range(3):
    statement(i)
Jan Christoph Terasa
  • 5,781
  • 24
  • 34
  • No, what I was going for was different. The number identifies the function name, I do not want to use this number as an argument. – Sarthak Saxena May 31 '21 at 05:52
0

Consider using this one eval() built in function in python; you could even use eval() when you want to pass parameters to the functions as you can see bellow. However, you should be careful when using eval with the OS module imported and taking input from the user with input() since eval() runs and executes everything it receives.

def statement1(num):
    print("Statement_{} -> number-{}".format(num, num))

def statement2(num):
    print("Statement_{} -> number-{}".format(num, num))

def statement3(num):
    print("Statement_{} -> number-{}".format(num, num))

for i in range(3):
    eval("statement{}({})".format(i+1, i+1))

Output would look like:

Statement_1 -> number-1
Statement_2 -> number-2
Statement_3 -> number-3
Cédric
  • 26
  • 5
0

You can choose the functions which have sign word,the run the choosed functions use vars() or globals() dict.

def statement1():
    print("s1")

def statement2():
    print("s2")

def statement3():
    print("s3")


functionSign = 'statement'
for varName in list(vars().keys()):
    if functionSign in varName:
        vars()[varName]()

Output:

   s1
   s2
   s3
Ramsey
  • 103
  • 7
0

Below is solution. It is inelegant but will work. Please wait for an elegant solution to appear.

import re
def statement1():
    # Do something
    print("Statement 1")

def statement2():
    # Do something
    print("Statement 2")

def statement3():
    # Do something
    print("Statement 3")

for i in dir():
    if re.fullmatch(r'^__[a-zA-Z0-9_]*__$' , i):
        continue
    else:
        if re.fullmatch(r'^statement[0-9]*$',i):
            eval('%s()'%i)

The output is

Statement 1
Statement 2
Statement 3
Amit
  • 2,018
  • 1
  • 8
  • 12
0

Functions are objects as well so you can used them as variables. Something like:

fns = [statement1, statement2, statement3]

for fn in fns:
    fn()
stan0
  • 11,549
  • 6
  • 42
  • 59