Search code examples
pythonnumpyfloating-pointsubclassduck-typing

Duck typing numpy float types


I am writing a custom encoding function for use with msgpack-python. I wish to convert any numpy.float object to float before letting msgpack-python serialise it. My encoding function looks like this:

def encode_custom(obj):        
    if issubclass(obj.__class__,np.float):
        obj = float(obj)
    return obj

which works just fine. However, the top voted answer at How do I check (at runtime) if one class is a subclass of another? suggests that this is a bad idea. I assume this is because this method doesn't use duck-typing.

Is there a way to duck-type the encoding function?

EDIT: Note that I only want float-like objects to convert to float. Objects that are better represented as another type (e.g. ints) should use that other type, even if they can be float()'d into a float object.


Solution

  • Special casing the type here is perfectly reasonable - because it sounds like you're feeding it into an API that doesn't work with duck-typing anyway.

    But as mentioned elsewhere, np.float is float, so that's not going to work. You probably want either isinstance(val, np.floating), or isinstance(val, np.inexact).

    For future reference, if you want to know what the entire class hierarchy (excluding abcs) is, you can get it with the .__mro__ property:

    >>> np.float32.__mro__
    (<class 'numpy.float32'>, <class 'numpy.floating'>, <class 'numpy.inexact'>, <class 'numpy.number'>, <class 'numpy.generic'>, <class 'object'>)