1

I already have a working, but in my oppinion not beautiful solution for a part of a long script.

My script uses several similar methods, that differ too much to combine. However I came to a point where I want to call one of those methods depending on a given variable.

The names of the methods are build up like this:

def read_A():
    #doing sth
def read_B():
    #doing sth else
def read_C():

etc.

Now I would like to call those methods in a pythonic way, when the letter ('A', 'B', 'C', ...) is given as a variable.

A non-pythonic solution would be:

if var == "A":
    read_A()
if var == "B":
    read_B() .....

And I hope to find a more pythonic solution that allows me to call those methods simply like this:

var = "A"
read_var()      #This would call the method 'read_A()'

Please mind that the code above is only an image of what I hope to do, it is not a working example!

martineau
  • 119,623
  • 25
  • 170
  • 301
yfro
  • 47
  • 9

5 Answers5

2

I dont see an issue with just using

if var == 'A':
    read_a()

but if you'd like to make it more 'pythonic' you could map your variables to the methods using a dictionary and execute it based on the result of what's stored in your dictionary:

def read_a():
    print('Running method read_a')

def read_b():
    print('Running method read_b')

switch = {'A': read_a, 'B': read_b}

case = 'A'
switch.get(case)()
>> 'Running method read_a'
case = 'B'
switch.get(case)()
>> 'Running method read_b'
Alan Kavanagh
  • 9,425
  • 7
  • 41
  • 65
  • The code is indeed working by using if, but it is required a lot and I would like to know if there is a way to shorten it in an elegant way – yfro Oct 09 '17 at 14:00
  • Hopefully this is elegant enough, it should reduce your lines of code if you have a lot of if statements – Alan Kavanagh Oct 09 '17 at 14:02
1

Stick the functions in a dictionary, and use the dictionary to dispatch to the chosen one:

read = {'A': read_a, 'B': read_b, 'C': read_c}
choice = 'A'
read[choice]()

On that last line, you lookup the function that matches your choice in the dictionary, then you immediately call it.

jacg
  • 2,040
  • 1
  • 14
  • 27
1

You can do it in this way if you have many functions named read_a, read_b...etc, instead of writing huge dictionary.

def read_a():
    print('Running method read_a')

def read_b():
    print('Running method read_b')

def read_c():
    print("running method read_c")

def read_d():
    print("running method read_d")

............
............

def read_z():
   print("running method read_z")

def _read_var(var):
    method = "read_{}".format(var.lower())
    try:
        eval(method)()
    except NameError:
        raise NotImplementedError

var = "A"
_read_var(var)# will invoke read_a method
Abdul Niyas P M
  • 18,035
  • 2
  • 25
  • 46
1

you may use next construction:

def execute_func(x):
    return {
        '0':read_A(),
        '1':read_B()
    }[x]

Set your variables instead '0' and '1' or more and pass your params to execute_func().

Andy
  • 11
  • 1
  • 1
    That executes both read_A and read_B and it just returns the solution of the one selected, you should remove the parenthesis from the dict and place them after the `}[x]` – Adirio Oct 09 '17 at 14:21
  • I tried it and was curious why it does that. This really helps – yfro Oct 09 '17 at 15:27
0
"""
modified from
https://stackoverflow.com/questions/65163600/how-to-call-a-class-method-given-its-name
"""


class MyClass(object):
    def __init__(self):
        pass

    def call_method_by_string(self, method_name):
        getattr(self, method_name)()  # call local method based on string

    def get_year(self):
        print("here")


if __name__ == "__main__":
    mc = MyClass()
    mc.call_method_by_string(method_name="get_year")
Markus Kaukonen
  • 334
  • 4
  • 10