2016-12-02 87 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