开发者

Can I create a Python Numpy ufunc from an unbound member method?

I would like to use numpy.frompyfunc to generate an unbound ufunc from an unbound member method. My concrete but failing attempts开发者_运维问答 look like

class Foo(object):
    def f(x,y,z):
        return x + y + z

Foo.g = numpy.frompyfunc(Foo.f,3,1)
i = Foo()
i.g(5,6,7)

where the last line fails with "TypeError: unbound method f() must be called with Foo instance as first argument (got int instance instead)". That error makes sense to me as Foo.f is unbound.

Despite it being deprecated, I thought I'd give new.instancemethod a shot:

import new
Foo.h = new.instancemethod(numpy.frompyfunc(Foo.f,3,1),None,Foo)
j = Foo()
j.h(5,6,7)

where the last line now fails with "TypeError: return arrays must be of ArrayType" which I don't understand.

My goal is to monkey patch Foo with ufunc-ready versions of its members. They must be member methods as they depend on a Foo instance's state (though that dependency is not shown here).

Any suggestions?


I must admit that I don't quite understand why you'd want f and g to be inside Foo class, but the following works:

>>> class Foo(object):
...     @staticmethod
...     def f(x, y, z):
...             return x+y+z
...
>>> Foo.g = numpy.frompyfunc(Foo.f, 3, 1)
>>> i = Foo()
>>> i.g(5, 6, 7)
18

EDIT: since you want to use instance data in your method, what you actualy need is a bound method:

>>> class Foo(object):
...     def f(self, x, y, z):
...             return x+y+z
...
>>> i = Foo()
>>> i.g = numpy.frompyfunc(i.f, 3, 1)
>>> i.g(5, 6, 7)
18

Of course, in real code you will probably want to assign g in Foo.__init__ , not outside of the class:

>>> class Foo(object):
...     def __init__(self):
...             self.g = numpy.frompyfunc(self.f, 3, 1)
...     def f(self, x, y, z):
...             return x+y+z
...
>>> i = Foo()
>>> i.g(5, 6, 7)
18


import numpy as np

class Foo(object):
    def f(self,x,y,z):
        return x + y + z

Add a g method to Foo:

def g(self,x,y,z):
    return np.frompyfunc(self.f,3,1)(x,y,z)
Foo.g = g

Calling g from an instance of Foo:

i = Foo()
print(i.g(np.array([5,6]),np.array([6,7]),np.array([7,8])))
# [18 21]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜