Generating a stub class
Carl Banks
imbosol at vt.edu
Thu Dec 5 20:29:44 EST 2002
Gerson Kurz wrote:
[snip]
> # generic stub class
> class genericstub:
> pass
>
> # create stub for my interface definition
> stub = genericstub()
> for method in dir(myinterface):
>
> # skip hidden methods
> if method[0] <> '_':
>
> def instance_method(*args):
> print "%s called given %s" % (method, args)
>
> setattr( stub, method, instance_method )
>
> # check if stub works
> stub.foo(1,2,3)
> stub.bar()
>
> ------------(snip here)------------
>
> This code won't work as (I) expected. It will result in
>
> foo called given (1, 2, 3)
> foo called given ()
>
> because, as I understand it, the "method" inside "instance_method" is
> a reference to the loop variable "method" used during the generation
> of the stub class.
Right. The reference to "method" inside "instance_method" is a global
variable, and refers to the global value of "method" at the time the
function is executed, not at the time it was defined (which is what
you want).
> My solution is creating a "method class" like this:
>
> class instance_method:
> def __init__(self, methodname):
> self.methodname = methodname
>
> def __call__(self, *args):
> print "%s called given %s" % (self.methodname, args)
>
> which works just fine. Is there an easier solution than that?
I would say this is the Pythonic way to do it for versions before 2.1.
Starting with Python 2.1, you can use lexical closures:
from __future__ import nested_scopes
def define_instance_method(methodname):
def instance_method(*args):
print "%s called given %s" % (methodname, args)
return instance_method
and create the stub method, inside your loop, this way:
setattr(stub,method,define_instance_method(method))
In Python 2.2, you don't need to import nested_scopes.
Even though Python now has nested scopes, some people still prefer
using a class for this kind of thing. I prefer to use a closure
myself.
--
CARL BANKS
More information about the Python-list
mailing list