Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Determining if a function is a method of a class within a decorator

Reply
Thread Tools

Determining if a function is a method of a class within a decorator

 
 
David Hirschfield
Guest
Posts: n/a
 
      06-30-2009
I'm having a little problem with some python metaprogramming. I want to
have a decorator which I can use either with functions or methods of
classes, which will allow me to swap one function or method for another.
It works as I want it to, except that I want to be able to do some
things a little differently depending on whether I'm swapping two
functions, or two methods of a class.

Trouble is, it appears that when the decorator is called the function is
not yet bound to an instance, so no matter whether it's a method or
function, it looks the same to the decorator.

This simple example illustrates the problem:

import inspect
class swapWith(object):
def __init__(self, replacement):
self.replacement = replacement

def __call__(self, thingToReplace):
def _replacer(*args, **kws):
import inspect
print
"replacing:",self.replacement,inspect.ismethod(sel f.replacement)
return self.replacement(*args, **kws)
return _replacer

class MyClass(object):

def swapIn(self):
print "this method will be swapped in"

@swapWith(swapIn)
def swapOut(self):
print "this method will be swapped out"

c = MyClass()
c.swapOut()


def swapInFn():
print "this function will be swapped in"

@swapWith(swapInFn)
def swapOutFn():
print "this function will be swapped out"

swapOutFn()


Both MyClass.swapIn and swapInFn look like the same thing to the
decorator, and MyClass.swapOut and swapOutFn look the same. So is there
a pattern I can follow that will allow me to determine whether the
objects I'm given are plain functions or belong to a class?

Thanks in advance,
-David

--
Presenting:
mediocre nebula.


 
Reply With Quote
 
 
 
 
Steven D'Aprano
Guest
Posts: n/a
 
      06-30-2009
On Mon, 29 Jun 2009 18:01:29 -0700, David Hirschfield wrote:

> I'm having a little problem with some python metaprogramming. I want to
> have a decorator which I can use either with functions or methods of
> classes, which will allow me to swap one function or method for another.
> It works as I want it to, except that I want to be able to do some
> things a little differently depending on whether I'm swapping two
> functions, or two methods of a class.
>
> Trouble is, it appears that when the decorator is called the function is
> not yet bound to an instance, so no matter whether it's a method or
> function, it looks the same to the decorator.


Then:

* use a naming convention to recognise methods (e.g. check if the first
argument is called "self" by looking at function.func_code.co_varnames);

* use two different decorators, or a decorator that takes an extra
"method or function argument";

* play around with the class metaclass and see if you can do something
special (and probably fragile);

* do the replacements after the class is created without decorator
syntax, e.g.:

Class.method1 = swapWith(Class.method2)(Class.method1)




> This simple example illustrates the problem:

[snip]


No it doesn't. It appears to work perfectly, from what I can guess you're
trying to accomplish.



Have you considered a possibly simpler way of swapping methods/functions?


>>> def parrot():

.... print "It's pining for the fjords."
....
>>> def cheeseshop():

.... print "We don't stock Cheddar."
....
>>> parrot, cheeseshop = cheeseshop, parrot
>>>
>>> parrot()

We don't stock Cheddar.
>>> cheeseshop()

It's pining for the fjords.


Admittedly, this doesn't let you do extra processing before calling the
swapped functions, but perhaps it will do for what you need.



--
Steven
 
Reply With Quote
 
 
 
 
Carl Banks
Guest
Posts: n/a
 
      07-01-2009
On Jun 29, 6:01*pm, David Hirschfield <dav...@ilm.com> wrote:
> So is there
> a pattern I can follow that will allow me to determine whether the
> objects I'm given are plain functions or belong to a class?
>
> Thanks in advance,




class HomemadeUnboundMethod(object):
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
print "is a function: %s" % self.func.func_name
return self.func(*args,**kwargs)
def __get__(self,obj,owner):
return HomemadeBoundMethod(obj,self.func)

class HomemadeBoundMethod(object):
def __init__(self,obj,func):
self.obj = obj
self.func = func
def __call__(self,*args,**kwargs):
print "is a method: %s" % self.func.func_name
return self.func(self.obj,*args,**kwargs)

class A(object):
@HomemadeUnboundMethod
def method(self): pass

@HomemadeUnboundMethod
def function(): pass

A().method()
function()



Just override the __call__ functions to do what you want the decorated
function to do. There are other little improvements you might make
(account for the owner parameter of __get__ for instance) but you get
the idea.


Carl Banks
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
refer to self in a decorator on a class method Yuccaplant Python 1 03-29-2010 09:53 AM
How to add a Decorator to a Class Method gregpinero@gmail.com Python 6 11-20-2007 07:04 PM
Why doesnt __getattr__ with decorator dont call __get_method in decorator glomde Python 5 03-29-2007 02:48 PM
Why is class decorator on method loosing self? c james Python 4 11-21-2006 08:03 PM
newb: Class Method determining it's actual class? Art Gillespie Ruby 5 10-08-2005 11:17 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57