-1

I have a class and within one of the methods of the class I have a string given from user input which is then mapped to the corresponding method (technically is a str representation of the method). How can I call this method without an instance of the class being created yet, i.e., with self. argument. I've included what I thought would work but it doesn't...

class RunTest():
      def __init__(self, method_name):
          self.method_name = method_name #i.e., method_name = 'Method 1'

      def initialize_test(self):
          mapping = {'Method 1': 'method1()', 'Method 2': 'method2()', ...}
          test_to_run = getattr(self, mapping[self.method_name])

      def method1(self):
          ....

      def method2(self):
          ....
Energya
  • 2,623
  • 2
  • 19
  • 24
  • What method are you trying to call? Does it belong to the class? – Robert Kearns Sep 27 '19 at 23:19
  • Depending on the string method_name, it would be one of method1() or method2() from the code above. So, to answer your second question, yes, it belongs to the class – keggythekeg Sep 27 '19 at 23:22
  • How would you set ```method_name``` without initiating the class? It is set when an instance is created. – Robert Kearns Sep 27 '19 at 23:26
  • Sorry I'm new to python... So you can't have a method depend on another? – keggythekeg Sep 27 '19 at 23:32
  • Actually I know you can have a method being called in another so as long as it has self.method(). I want to do the same except this method is in string format. I want to take away the strings and have it work as if it were self.method1() (or self.method2()) – keggythekeg Sep 27 '19 at 23:37
  • Remove the parenthesis in your dictionary. You are mapping not functions but their calls, which gives you the result of them. Also I suggest to save it as `self.test_to_run` so you can call it later. – sashaaero Sep 28 '19 at 00:29

1 Answers1

1

If i understand correctly you would like to map your classes attribute to a method based on user input. This should do what you want it to:

class YourClass:
    def __init__(self, method_name):
        mapping = {'Method 1': self.method_one,
                    'Method 2': self.method_two}

        self.chosen_method = mapping[method_name]

    def method_one(self):
        print('method one')

    def method_two(self):
        print('method two')

while True:
    name = input("enter 'Method 1' or 'Method 2'")
    if name != 'Method 1' and name != 'Method 2':
        print('Invalid entry')
    else:
        break

your_class = YourClass(name)
your_class.chosen_method()

This avoids needing to use getattr() at all. Make sure that in your mapping dictionary you do not have parenthesis on the methods (ex. {'Method 1': self.method_one()...). If you do then chosen_method will equal whatever that method returns.

Robert Kearns
  • 1,631
  • 1
  • 8
  • 15
  • Thank you so much! This works! This reassembles my other method except for the removal of the parentheses within the dictionary. How come python still recognizes the function but doesn’t call it when we remove the parentheses? – keggythekeg Sep 28 '19 at 01:58
  • Yes it does, also the quotes are removed so it is not a string. If you kept it as a string you would have to use a different method to access it. When you put the parentheses it runs the function. So whatever the function returns is what your key equals. – Robert Kearns Sep 28 '19 at 02:01