views:

153

answers:

2

Hello, 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.

+2  A: 

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
SilentGhost
@SilentGhost -- If I had just function like `def run` with the variable `var` how could I get that attribute from another class? Thanks
chrissygormley
@chriss: are you asking about the argument? you could just pass it in the normal call (last brackets): `getattr(A(), 'run')('arg1')`
SilentGhost
@SilentGhost -- +1 Thanks for that but I have to leave the question open as this answer doesn't answer the question on how to pass the arg from the command line in that class.
chrissygormley
@chriss: are you expecting that I would re-write all your code for you? :)
SilentGhost
@SilentGhost -- No, the question I asked was to pass the variable into script via the command line. It does this but I wanted to know how to pass it into a the function if it was inside a class. The getattr() is useful but it still does not do anything for the question I asked. I will add to the question to make it clearer to understand.
chrissygormley
@chriss: having read your edits, I'm sure that my answer is perfectly adequate. I'll change now a small bit to reflect passing of the argument, but I don't see how else I can help you.
SilentGhost
@SilentGhost -- Sorry, I was getting slightly confused. Thanks for the answer helped me alot to get the above code working. +1
chrissygormley
+1  A: 

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.

Jeffrey Harris
@Jeffrey Harris -- +1, Thanks
chrissygormley