(original) (raw)

On Wed, Jun 27, 2018 at 12:50 PM Stephan Hoyer <shoyer@gmail.com> wrote:
One concern this does raise is how to handle methods like those on RandomState, even though methods like random\_like() don't currently exist. Distribution objects from scipy.stats could have similar use cases.

So perhaps it's worth "future proofing" the interface by passing \`obj\` and \`method\` to \_\_array\_function\_\_ rather than only \`func\`. It is slower to call a func via func.\_\_call\_\_ than func, but only very marginally (\~100 ns in my tests).

I did a little more digging, and turned up the \_\_self\_\_ and \_\_func\_\_ attributes of bound methods:
https://stackoverflow.com/questions/4679592/how-to-find-instance-of-a-bound-method-in-python

So we might need another decorator function, but it seems that the current interface would actually suffice just fine for overriding methods. I'll update the NEP with some examples. It will look something like:

def \_\_array\_function\_\_(self, func, types, args, kwargs):
...
if isinstance(func, types.MethodType):
object = func.\_\_self\_\_
unbound\_func = func.\_\_func\_\_
...

Given that functions are the most common case, I think it's best to keep with \`func\` as the main interface, but it's good to know that this does not preclude overriding methods.