Vuoi controllare se qualche oggetto
agisce come un numero in determinate circostanze
Se stai usando Python 2.5 o precedente, l'unico vero modo è controllare alcune di quelle "determinate circostanze" e vedere.
In 2.6 o superiore, puoi usare isinstance
con numbers.Number - una classe base astratta (ABC) che esiste esattamente per questo scopo (esistono molti più ABC nelcollections
modulo per varie forme di collezioni / contenitori, sempre a partire da 2.6; e, inoltre, solo in queste versioni, puoi facilmente aggiungere le tue classi base astratte se necessario).
Bach a 2.5 e precedenti, "può essere aggiunto 0
e non è iterabile" potrebbe essere una buona definizione in alcuni casi. Ma devi davvero chiederti cosa stai chiedendo che ciò che vuoi considerare "un numero" deve essere sicuramente in grado di fare e cosa deve essere assolutamente incapace di fare - e controllare.
Ciò potrebbe essere necessario anche nella versione 2.6 o successiva, forse allo scopo di effettuare le tue registrazioni per aggiungere tipi a cui tieni che non sono già stati registrati numbers.Numbers
- se desideri escludere alcuni tipi che affermano di essere numeri ma tu semplicemente non riesco a gestirlo, questo richiede ancora più attenzione, poiché gli ABC non hannounregister
metodo [[per esempio potresti creare il tuo ABC WeirdNum
e registrare lì tutti questi tipi strani per te, quindi prima controlla per isinstance
salvarli prima di procedere al controllo isinstance
del normale numbers.Number
per continuare con successo.
A proposito, se e quando è necessario controllare se x
puoi o non puoi fare qualcosa, in genere devi provare qualcosa del tipo:
try: 0 + x
except TypeError: canadd=False
else: canadd=True
La presenza di __add__
per sé non dice nulla di utile, poiché ad esempio tutte le sequenze lo hanno allo scopo di concatenarsi con altre sequenze. Questo controllo è equivalente alla definizione "un numero è qualcosa tale che una sequenza di tali cose è un singolo argomento valido per la funzione incorporata sum
", per esempio. Tipi totalmente strani (ad esempio quelli che sollevano l'eccezione "sbagliata" quando sommata a 0, come, ad esempio, a ZeroDivisionError
oValueError
& c) propagheranno l'eccezione, ma va bene, fai sapere all'utente al più presto che questi tipi pazzi non sono accettabili in bene azienda;-); ma, un "vettore" sommabile a uno scalare (la libreria standard di Python non ne ha uno, ma ovviamente sono popolari come estensioni di terze parti) darebbe anche il risultato sbagliato qui, quindi (ad es.quello "non può essere iterabile" (ad esempio, controlla che iter(x)
solleva TypeError
, o per la presenza di un metodo speciale __iter__
- se sei in 2.5 o precedente e quindi hai bisogno dei tuoi controlli).
Una breve occhiata a tali complicazioni può essere sufficiente per motivarti a fare affidamento invece su classi base astratte ogniqualvolta sia fattibile ... ;-).