Pass in a value into Python Class through command line

12,589

Solution 1

you might find getattr useful:

>>> argv = ['function.py', 'run', 'Hello']
>>> class A:
    def run(self, *args):
        print(*args)


>>> getattr(A(), argv[1])(*argv[2:])
Hello

Solution 2

It sounds like rather than:

self.function = self.module.__dict__[self.functionName]

you want to do something like (as @SilentGhost mentioned):

self.function = getattr(some_class, self.functionName)

The tricky thing with retrieving a method on a class (not an object instance) is that you are going to get back an unbound method. You will need to pass an instance of some_class as the first argument when you call self.function.

Alternately, if you are defining the class in question, you can use classmethod or staticmethod to make sure that some_class.function_you_want_to_pick will return a bound function.

Share:
12,589
chrisg
Author by

chrisg

All things serverless at the minute. Enjoy travelling and getting my hands on any piece of technology that is of course going to make my life amazing :)

Updated on June 04, 2022

Comments

  • chrisg
    chrisg about 2 years

    I have got some code to pass in a variable into a script from the command line. I can pass any value into function for the var arg. The problem is that when I put function into a class the variable doesn't get read into function. The script is:

    import sys, os
    
    def function(var):
        print var
    
    class function_call(object):
        def __init__(self, sysArgs):
            try:
                self.function = None
                self.args = []
                self.modulePath = sysArgs[0]
                self.moduleDir, tail = os.path.split(self.modulePath)
                self.moduleName, ext = os.path.splitext(tail)
                __import__(self.moduleName)
                self.module = sys.modules[self.moduleName]
                if len(sysArgs) > 1:
                    self.functionName = sysArgs[1]
                    self.function = self.module.__dict__[self.functionName]
                    self.args = sysArgs[2:]
            except Exception, e:
                sys.stderr.write("%s %s\n" % ("PythonCall#__init__", e))
    
        def execute(self):
            try:
                if self.function:
                    self.function(*self.args)
            except Exception, e:
                sys.stderr.write("%s %s\n" % ("PythonCall#execute", e))
    
    if __name__=="__main__":
        function_call(sys.argv).execute()
    

    This works by entering ./function <function> <arg1 arg2 ....>. The problem is that I want to to select the function I want that is in a class rather than just a function by itself. The code I have tried is the same except that function(var): is in a class. I was hoping for some ideas on how to modify my function_call class to accept this.

    If i want to pass in the value Hello I run the script like so -- python function_call.py function Hello. This then prints the var variable as Hello.

    By entering the variable into the command lines I can then use this variable throughout the code. If the script was a bunch of functions I could just select the function using this code but I would like to select the functions inside a particular class. Instead of python function.py function hello I could enter the class in as well eg. python function.py A function hello.

    Also I have encounter that I have problem's saving the value for use outside the function. If anyone could solve this I would appreciate it very much. _________________________________________________________________________________

    Amended code. This is the code that work's for me now.

    class A:
        def __init__(self):
            self.project = sys.argv[2]
        def run(self, *sysArgs):
            pass
        def funct(self):
            print self.project
    
    class function_call(object):
        def __init__(self, sysArgs):
            try:
                self.function = None
                self.args = []
                self.modulePath = sysArgs[0]
                self.moduleDir, tail = os.path.split(self.modulePath)
                self.moduleName, ext = os.path.splitext(tail)
                __import__(self.moduleName)
                self.module = sys.modules[self.moduleName]
                if len(sysArgs) > 1:
                    self.functionName = sysArgs[1]
                    self.function = getattr(A(), sysArgs[1])(*sysArgs[2:])
                    self.args = sysArgs[2:]
            except Exception, e:
                sys.stderr.write("%s %s\n" % ("PythonCall#__init__", e))
    
        def execute(self):
            try:
                if self.function:
                    self.function(*self.args)
            except Exception, e:
                sys.stderr.write("%s %s\n" % ("PythonCall#execute", e))
    
    
    if __name__=="__main__":
        function_call(sys.argv).execute()
        inst_A = A()
        inst_A.funct()
    

    Thanks for all the help.