2014-05-09 12 views
5

Ho una funzioneCome controllare se len è valido

def foo(bar): 
    #do some things 
    len(bar) 

Se chiamo

foo(42) 

viene generata un'eccezione di

TypeError: object of type 'int' has no len()

Come posso controllare se il immesso il valore può essere utilizzato con len()?

risposta

8

si può fare:

if hasattr(bar, '__len__'): 
    pass 

In alternativa, si può prendere il TypeError.

+2

Questo non dovrebbe essere '__len__ in dir (bar)'? In ogni caso, usare 'hasattr' è meglio se si utilizza questo approccio – Daenyth

+0

Anche un oggetto ha l'attributo' __len__', non significa che sia valido (o OP dovrebbe definire ciò che è ** valido **). Ad esempio, una classe può definire una funzione '__len__' che restituisce un' str', e passerà il test 'hasattr', ma lancia comunque l'eccezione' TypeError' quando si chiama 'len()'. Questo è esattamente ciò per cui è stata progettata la gestione delle eccezioni **, punendoli per avermi dato un input sporco. – Nier

5

È possibile farlo utilizzando try e except per i migliori risultati:

def foo(bar): 
    #do some things 
    try: 
     print(len(bar)) 
    except TypeError: 
     print('Input not compatible with len()') 
4

È possibile verificare se l'oggetto è Sized:

import collections 

if isinstance(bar, collections.Sized): 

Il test isinstance() è vero se tutti i metodi astratti di Sized sono implementati; in questo caso è solo __len__.

Personalmente, avevo appena intercettare l'eccezione invece:

try: 
    foo(42) 
except TypeError: 
    pass # oops, no length 
+0

+1 per 'Sized'. – Daenyth

2

Dal len()calls __len__() magic method sotto il cofano, è possibile controllare se un oggetto ha __len__ metodo definito con l'aiuto di hasattr():

>>> def has_len(obj): 
...  return hasattr(obj, '__len__') 
... 
>>> has_len([1,2,3]) 
True 
>>> has_len('test') 
True 
>>> has_len(1) 
False