Python は強く型付けされた言語であるというリンクに遭遇しました。
しかし、強く型付けされた言語ではこれができないと思いました:
bob = 1
bob = "bob"
強く型付けされた言語は実行時に型の変更を受け入れないと思っていました。強い型/弱い型の定義が間違っている(または単純すぎる)のかもしれません。
では、Python は強く型付けされた言語でしょうか、それとも弱く型付けされた言語でしょうか?
ベストアンサー1
Python は強力かつ動的に型付けされています。
- 強い型付けとは、値の型が予期しない方法で変更されないことを意味します。Perl で発生する可能性があるように、数字のみを含む文字列が魔法のように数字になることはありません。型の変更には必ず明示的な変換が必要です。
- 動的型付けとは、変数に型がある静的型付けとは対照的に、実行時オブジェクト (値) に型があることを意味します。
あなたの例に関して言えば
bob = 1
bob = "bob"
これが機能するのは、変数に型がなく、任意のオブジェクトに名前を付けることができるためです。 の後では が を返しますが、 の後ではが を返します。( は通常の関数であるため、引数を評価してから値の型を返すことに注意してください。bob=1
)type(bob)
int
bob="bob"
str
type
これを、弱い静的型付けであったためポインタと整数がほぼ互換性のある C の古い方言と比較してください。(最近の ISO C では多くの場合変換が必要ですが、私のコンパイラはデフォルトでこれに対してまだ寛容です。)
強い型付けと弱い型付けは、ブール値の選択というよりも連続体であることを付け加えておきます。C++ は C よりも強い型付け (より多くの変換が必要) ですが、ポインター キャストを使用することで型システムを破壊することができます。
Python のような動的言語の型システムの強さは、実際にはそのプリミティブとライブラリ関数がさまざまな型にどのように反応するかによって決まります。たとえば、+
はオーバーロードされているため、2 つの数値または2 つの文字列では機能しますが、文字列と数値では機能しません。これは、+
が実装されたときに行われた設計上の選択ですが、言語のセマンティクスから必然的に必要というわけではありません。実際、+
カスタム型をオーバーロードすると、何でも暗黙的に数値に変換できます。
def to_number(x):
"""Try to convert function argument to float-type object."""
try:
return float(x)
except (TypeError, ValueError):
return 0
class Foo:
def __init__(self, number):
self.number = number
def __add__(self, other):
return self.number + to_number(other)
クラスのインスタンスはFoo
他のオブジェクトに追加できます。
>>> a = Foo(42)
>>> a + "1"
43.0
>>> a + Foo
42
>>> a + 1
43.0
>>> a + None
42
厳密に型付けされた Python では、 と のオブジェクトを追加してもまったく問題ありませんint
がfloat
、 は のオブジェクトを返しますfloat
(例:int(42) + float(1)
は を返します43.0
)。一方、型間の不一致のため、Haskell では次の を実行しようとするとエラーが発生します(42 :: Integer) + (1 :: Float)
。これにより、Haskell は厳密に型付けされた言語となり、型は完全に分離され、制御された形式のオーバーロードのみが型クラスを介して可能になります。