pythonarraysnumpy

Is numpy.divide a function or a class or something else?


In this code:

import numpy as np

a = np.array([1,2,3])
b = np.array([2,3,4])

c = np.divide(a,b)
d = np.divide.outer(a,b)
e = np.outer(a,b)

print(f"{c=}\n{d=}\n{e=}")

It seems that numpy.divide contains outer, meanwhile numpy.divide is a function.

I’m really confused why numpy.divide behaves like both class(because it could contain something) and function(because it is callable).

print(type(np.divide)) returns <class 'numpy.ufunc'>. But why ufunc could have this effect?

My question is that: why np.divide is callable, meanwhile there is functions that is belongs to np.divide? sys.stderr.write is not a similar case as sys.stderr is not callable.


Solution

  • An easy way to answer this type of question:

    import numpy as np
    
    print(type(np.divide))
    

    Result:

    <class 'numpy.ufunc'>
    

    How can you call a class, or rather an instance of it? If a class has __call__, it instances can be called, and this ufunc is callable:

    print(type(np.divide.__call__))
    

    Result:

    <class 'method-wrapper'>
    

    It's not just that "a similar notation is used" - the instance is callable, no different from a function. A regular Python function is just an instance of the function class:

    def fun():
        ...
    
    
    print(type(fun))
    print(type(fun.__call__))
    

    Result:

    <class 'function'>
    <class 'method-wrapper'>
    

    So, numpy.divide is both a function and an object, which is an instance of a class. If something has the type class 'something', it's not itself a class, it's an instance of that class, an object.