私はいくつかの古いPythonのようなことをしているコードを見つけました:
_if type(var) is type(1):
...
_
予想どおり、_pep8
_はisinstance()
の使用を推奨していることについて不満を言っています。
今、問題はnumbers
モジュールがPython 2.6で追加され、Python 2.5+
したがって、if isinstance(var, Numbers.number)
は解決策ではありません。
この場合、適切な解決策はどれですか?
Python 2では、 types
モジュール を使用できます。
_>>> import types
>>> var = 1
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
>>> isinstance(var, NumberTypes)
True
_
Tupleを使用して複数のタイプに対してテストすることに注意してください。
内部では、IntType
はint
などの単なるエイリアスです。
_>>> isinstance(var, (int, long, float, complex))
True
_
complex
タイプでは、pythonが複素数をサポートするようにコンパイルされている必要があります。これを防ぐには、try/exceptブロックを使用します。
_>>> try:
... NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
... except AttributeError:
... # No support for complex numbers compiled
... NumberTypes = (types.IntType, types.LongType, types.FloatType)
...
_
または、タイプを直接使用する場合:
_>>> try:
... NumberTypes = (int, long, float, complex)
... except NameError:
... # No support for complex numbers compiled
... NumberTypes = (int, long, float)
...
_
Python 3 types
は標準タイプのエイリアスを持たなくなり、complex
は常に有効になり、long
vs int
差なので、Python 3では常に以下を使用します:
_NumberTypes = (int, float, complex)
_
最後になりましたが、 _numbers.Numbers
_ abstract base type (Python 2.6)の新機能)を使用して、派生しないカスタム数値型もサポートできます上記のタイプから直接:
_>>> import numbers
>>> isinstance(var, numbers.Number)
True
_
このチェックは、decimal.Decimal()
およびfractions.Fraction()
オブジェクトのTrue
も返します。
このモジュールは、complex
タイプが有効になっていると仮定しています。そうでない場合、インポートエラーが発生します。
Python 2は、数値int
、float
、long
およびcomplex
and python 3.x
は3:int
、float
およびcomplex
をサポートします
>>> num = 10
>>> if isinstance(num, (int, float, long, complex)): #use Tuple if checking against multiple types
print('yes it is a number')
yes it is a number
>>> isinstance(num, float)
False
>>> isinstance(num, int)
True
>>> a = complex(1, 2)
>>> isinstance(a, complex)
True
ダックタイピング でこれを使用しているものに応じて、より良いアプローチになる可能性があります( 確かに一般的に推奨 ) 。 Martijn Pietersのアプローチの問題点は、リストからいくつかのタイプの数値が常に欠落することです。私の頭の上では、あなたのコードは動作しません:sympy有理数、任意精度の整数、複素数の実装。
1つの選択肢は、次のような関数を記述することです。
def is_number(thing):
try:
thing + 1
return True
except TypeError:
return False
このコードは、数値の合理的な実装で機能するはずです。もちろん、大きな欠点もあります:それはまた、多くの非数値の不合理な実装でも動作します(つまり、プラス演算子がオーバーロードされて整数を受け入れる場合)。
別の選択肢(何かが数字であるかどうかを知る必要性に応じて)は、それが数字であると仮定することです。そうでない場合は、コードのどのビットでも数字が必要なエラーがスローされます。
これらのアプローチが(一部の人々とは異なり)常に優れているとは言っていません。