[Pyrex] pyrex functions to replace a method (Re: replace a method in class: how?)
Lenard Lindstrom
len-l at telus.net
Wed Jun 28 18:40:15 UTC 2006
On 28 Jun 2006 at 7:02, Brian Blais wrote:
> Greg Ewing wrote:
> > Brian Blais wrote:
> >> I have found a very similar problem trying to replace a method using a
> >> function defined in pyrex.
> >
> >
> > What *should* work is to define the method inside a
> > class in Pyrex (plain class, not extension type) and
> > extract it out of the class's __dict__. That's because
> > Pyrex pre-wraps a function defined in a class in an
> > unbound method object before putting it in the class.
> >
>
> So I tried:
>
> #---------------------------------------------------------------------------------
>
> #module_pyrex.pyx
>
> class update_funcs:
>
> def pyrex_update_within_class(self,val):
> print "pyrex module within class",val
>
>
> #---------------------------------------------------------------------------------
>
> #(adding to test_replace_method.py)
>
> This.update4=module_pyrex.update_funcs.__dict__['pyrex_update_within_class']
>
> t.update4('pyrex within class') # doesn't work
>
> #---------------------------------------------------------------------------------
>
> and get:
>
> TypeError: unbound method pyrex_update_within_class() must be called with
> update_funcs instance as first argument (got str instance instead)
>
>
> did I do this wrong?
Nothing. Python's method type is just too specialized to work as Greg
suggested. You will have to provide your own method descriptor. This
works:
#--------------------------------------------------------------------
#module_pyrex.pyx
cdef extern from "python.h":
object PyMethod_New(object func, object self, object cls)
# Yes, this has to be an extension type in Pyrex.
cdef class InstanceMethod:
cdef object fn
def __init__(self, fn):
self.fn = fn
def __get__(self, instance, owner):
return PyMethod_New(self.fn, instance, owner)
def pyrex_update_within_class(self,val):
print "pyrex module within class",val
pyrex_update_within_class = InstanceMethod(pyrex_update_within_class)
#--------------------------------------------------------------------
#(Make this replacement in main py module of original posting)
This.update3=module_pyrex.pyrex_update_within_class
#--------------------------------------------------------------------
InstanceMethod is minimal. Additions may be to make the fn attribute
readable and a __call__ method that calls fn directly.
Lenard Lindstrom
<len-l at telus.net>
More information about the Pyrex
mailing list