2016-12-02 182 views
0

我正在写一个自定义编码函数与msgpack-python一起使用。我希望将任何numpy.float对象转换为float,然后让msgpack-python对它进行序列化。我的编码功能看起来像这样:鸭子打字numpy浮动类型

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

它工作得很好。然而,How do I check (at runtime) if one class is a subclass of another?顶部投票答案表明这是一个坏主意。我认为这是因为这种方法不使用鸭子打字。

有没有办法鸭式编码功能?

编辑:请注意,我只想浮动般的对象转换为浮动。更好地表示为另一种类型(例如整数)的对象应该使用该其他类型,即使它们可以在浮点对象中使用。

+2

'尝试:除了ValueError异常回报率浮动(OBJ) :return obj' – SethMMorton

+0

@SethMMorton这也将整数转换为浮点数。 –

+1

在某些情况下这是一个坏主意。你特别说过你想转换numpy浮点数,所以这看起来很好。不过,我建议只使用'isinstance(obj,np.float)'。 –

回答

2

这里的特殊外壳是非常合理的 - 因为它听起来像你喂它进入一个API,无论如何都不能用鸭子打字。

但正如其他地方提到的,np.float is float,所以这是行不通的。您可能需要isinstance(val, np.floating)isinstance(val, np.inexact)

以供将来参考,如果你想知道什么(不含abc S)整个类层次结构,你可以用.__mro__财产得到它:

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

__mro__提示非常感谢。 – Charlie

+0

或'np.float32.mro()',即通过一种方法,其中MRO表示_方法分辨率order_ –

0

你可以调用转换NumPy的标量到Python标量的NumPy的例程之一:

try: 
    return obj.item() 
except AttributeError: 
    return obj 

try: 
    return obj.tolist() # yes, tolist. It won't return a list here. 
except AttributeError: 
    return obj 

注意,这可能是最好只用isinstance(obj, numpy.float64),或isinstance(obj, (numpy.float32, numpy.float64))。鸭子打字对于像iterables这样的事情是有意义的,在那里你试图把它们当作迭代对象,如果它起作用,你就知道它们是可迭代的。这里?你试图把你的对象当作一个numpy标量来处理,如果它有效,你就知道...该对象有一个item方法或者一个tolist方法。这不是真的你感兴趣的信息。

如果要检查对象是否具有实际,具体的类型,而不是检查isinstance一般是什么样的操作提供,要走的路。

0

任何python问题的数字1答案是“它取决于”。使用鸭式输入法时,只需使用该对象并假定其正确,并在发生错误时捕获异常。在你的情况下,这将是:

def encode_custom(obj): 
    """Strict type checking: change to float, but raise ValueError 
    on fail and let upper level deal with it.""" 
    return float(obj) 

def encode_custom(obj): 
    """Loose type checking: change to float or return unchanged""" 
    try: 
     return float(obj) 
    except ValueError: 
     return obj 

这将适用于各种浮动和所有可以转换为浮动。诸如np.int16np.bool_str(如果它恰好表示一个int或float)。现在到“它取决于”。如果你的程序将这些非浮动事物定义为垃圾并且你想要出错,那么这很好,如果你想让所有这些东西变得隐蔽或者糟糕。

在这种情况下,不是检查子类,而是检查实例,以便处理正在进行的任何奇怪的多重继承或元编程。

def encode_custom(obj):   
    if isinstance(obj,np.float): 
     obj = float(obj) 
    return obj 
+2

请注意,'np.float'只是Python内置'float'的另一个名称。更重要的是,请注意'isinstance(np.float32(1.0),float)'返回'False'。 –

+1

@WarrenWeckesser - 有趣。我检查了'np.float64',它工作。 'np.float32'的'issubclass'也不起作用。嗯.... – tdelaney