FAN wrote: > I want to define some function in python script dynamicly and call > them later, but I get some problem. I have tried the following: > > ################################## > # code > ################################## > class test: > def __init__(self): > exec("def dfunc(msg):\n\tprint msg\nprint 'exec def function'") > dfunc('Msg in init ...') # it work > > def show(self, msg): > dfunc(msg) # doesn't work ! > I think this maybe cause by the scope of function definition, for the > first call of 'dfunc' in __init__ work.
The exec statement syntax is: "exec" expression ["in" expression ["," expression]] http://www.python.org/doc/2.4.1/ref/exec.html Without the optional part, the default is to execute the statement in the current scope. As Python allows defining nested functions, the dfunc() function is local to the the __init__() function and doesn't exists in the class scope or the global scope. class Test2(object): def __init__(self): exec "def dfunc(msg):\n\tprint msg\nprint 'exec def function'" \ in globals() dfunc('Msg in init ...') # it work def show(self, msg): dfunc(msg) d2 = Test2() d2.show('hello') But I would not advise you to use exec this way... > So I tried to define the > function as a member function of class 'test', but this time even the > first call doesn't work: > > ################################## > # code > ################################## > class test: > def __init__(self): > exec("def dfunc(self,msg):\n\tprint msg\nprint 'exec def function'") > self.dfunc('Msg in init ...') Here again, for the function to become a method of the class, it has to be defined in the scope of the class - not in the scope of the __init__() function: class Test(object): exec "def dfunc(self,msg):\n\tprint msg\nprint 'exec def function'" def __init__(self): self.dfunc('Msg in init ...') def show(self, msg): self.dfunc(msg) d = Test() d.show('hello') > Is there any way I can solve this problem? The first question that comes to mind is "aren't you trying to solve the wrong problem ?". If you tell us more about your real use case, we may point you to others - possibly better - ways of solving it. I don't mean that it's wrong to use the exec statement, but my experience is that I've never had a use case for it in 5+ years of Python programming. Everytime I thought I needed exec, it turned out that there was a much better solution, usually involving callables, closures, properties, descriptors, metaclasses, or any combination of... Also, the fact that you seems to be at lost with Python's inner mechanisms makes me think you probably don't know other - possibly better - ways to solve your problem. If what you need is to "parameterize" a function, closures and nested functions may be a better solution. A silly exemple: def makeadder(step): def adder(num): return step + num return adder add1 = makeadder(1) add3 = makeadder(3) add1(1) => 2 add1(2) => 3 add2(1) => 3 add2(2) => 4 Functions being first-class citizen in Python, it's easy to parameterize a function with another: import sys def buildfun(funtest, funiftrue, funiffalse): def built(arg): if funtest(arg): print "%s is true for %s" % (funtest, arg) funiftrue("%s\n" % str(arg)) else: print "%s is false for %s" % (funtest, arg) funiffalse("%s\n" % str(arg)) return built b = buildfun(lambda arg: arg == 42, sys.stdout.write, sys.stderr.write) b(42) b("toto") Another possibility is to work with callable objects. A function in Python is just an object (an instance of the function class), and any object having a __call__() method is callable: class Greeter(object): def __init__(self, name, greeting="hello %(who)s, my name is %(name)s"): """ greeting is supposed to be a format string with %(name)s and %(who)s in it """ self.name = name self.greeting = greeting def __call__(self, who): return self.greeting % {'name': self.name, 'who': who} Yet another possibility is to go with metaclasses, but I won't give an exemple here !-) HTH -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list