11

私は Java の世界から来ましたが、コードのコンパイル中にエラーが発生しないこと以外に、Python の動的型付けの優れた点は何でしょうか?

Python のタイピングは好きですか? 大きなプロジェクトで役に立った例はありますか? ちょっとミスしやすいんじゃない?

4

7 に答える 7

17

一般的なケースでは、静的型チェックは決定できません。これは、静的にタイプ セーフであるが、タイプ チェッカーが静的にタイプ セーフであることを証明できないプログラムが存在することを意味します。したがって、タイプ チェッカーはそれらのプログラムを拒否する必要があります。

言い換えれば、タイプチェッカーが作成を許可しないタイプセーフなプログラムがあります。または、もっと簡潔に言うと、静的型付けは、特定のプログラムを作成することを妨げます。

これは、Java だけでなく、すべての静的型付け全般に当てはまります。

特にJavaに関しては、かなりくだらない型システムを持っています。その型システムは、非常に単純なプロパティでさえ表現できるほど表現力がありません。例: の型のどこでstatic void java.util.Arrays.sort(Object[] a)、結果をソートする必要があると実際に言っているのでしょうか? または、配列要素を部分的に順序付けする必要がありますか?

Java のもう 1 つの問題は、型システムにトラックが通れるほど大きな穴があることです。

String[] a = new String[1];
Object[] b = a;
b[0] = 1; // ArrayStoreException

この特定のケースの問題は、共変配列です。配列が共変かつ型安全であることは単純に不可能です。

Java は、静的型付けの煩わしさをすべて兼ね備えていますが、利点はありません。だから、あなたは面倒を取り除くこともできます。

ただし、これは普遍的ではないことに注意してください。トレードオフがあまり明確でない、はるかに優れた型システムを持つ他の言語があります。

たとえば、これは Python で史上最も愚かな言語ベンチマーク (フィボナッチ) です。

def fib(n):
    if n < 2: return n
    return fib(n-2) + fib(n-1)

および Java:

int fib(int n) {
    if (n < 2) return n;
    return fib(n-2) + fib(n-1);
}

そこには、静的型付けにのみ関連するかなりの混乱があることに注意してください。比較をより公平にするために、Python の構文と Java のセマンティクスを持つ言語を想像してみましょう。

def fib(n: int) -> int:
    if n < 2: return n
    return fib(n-2) + fib(n-1)

[興味深い補足: Python 3.x でオプションの静的型注釈が追加されたことにより、これ実際には有効な Python コードでもありますが、注釈は単なる注釈であるため、静的に型安全ではないことは明らかです。実際にはどこでもチェックされることはありません。]

そこに明確な混乱があります。ただし、Haskell では次のようになります。

fib n
  |     n < 2 = n
  | otherwise = fib (n-2) + fib (n-1)

Python バージョンとは異なり、これ完全に静的にタイプ セーフですが、タイプ関連の混乱はありません。

この特定のケースでは、静的型付けと動的型付けの利点の間の問題はあまり明確ではありません。

ちなみに、より慣用的な Haskell バージョンは、おそらく次のようになります。

fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)

またはこれ:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

実際、Java と Python のより重要な違いは、Java が静的に型付けされ、Python が動的に型付けされるということではなく、Java が優れたプログラミング言語ではないのに対し、Python. つまり、Java は静的に型付けされているからではなく、がらくただから常に負けるのです。BASIC と Haskell を比較すると、Haskell が明らかに勝っていますが、静的に型付けされているからではなく、BASIC がくだらないからです。

より興味深い比較は、Java と BASIC、または Python と Haskell です。

于 2010-09-01T20:16:15.333 に答える
13

自明ではないJavaプログラムの大部分には、動的型付けが含まれていると思います。

Javaでオブジェクトから明示的な型へのキャストを行うたびに、動的型チェックを行っています。これには、ジェネリックが1.5で導入される前のコレクションクラスのすべての使用が含まれます。実際、Javaジェネリックは、実行時まで一部の型チェックを延期することができます。

Javaリフレクションを使用するたびに、動的型チェックを実行します。これには、テキストファイル内のクラスまたはメソッド名から実際のクラスまたはメソッドへのマッピングが含まれます。たとえば、SpringXML構成ファイルを使用するたびに。

これにより、Javaプログラムは脆弱になり、エラーが発生しやすくなりますか?Javaプログラマーは、時間のかなりの部分を、誤った動的型付けの問題を追跡して修正するために費やしていますか?おそらくそうではありません-そしてPythonプログラマーもそうではありません。

動的型付けの利点のいくつか:

  • 継承への依存度が大幅に低下しました。大規模な継承ツリーを持つJavaプログラムを見たことがあります。Pythonプログラムは、多くの場合、継承をほとんどまたはまったく使用せず、ダックタイピングを使用することを好みます。
  • 真にジェネリックなコードを書くのは簡単です。たとえば、min()関数とmax()関数は、整数、文字列、浮動小数点数、適切な比較メソッドを持つクラス、リスト、タプルなど、同等のタイプのシーケンスを取ることができます。
  • より少ないコード。Javaコードの大部分は、目前の問題の解決には何の貢献もしていません。型システムを満足させるためだけに存在しています。Pythonプログラムが同等のJavaプログラムの5分の1のサイズである場合、書き込み、保守、読み取り、および理解するためのコードは5分の1になります。別の言い方をすれば、Pythonの信号対雑音比ははるかに高くなっています。
  • より速い開発サイクル。これは、少ないコードと密接に関連しています。型やクラスについて考える時間が減り、取り組んでいる問題の解決について考える時間が増えます。
  • AOPはほとんど必要ありません。Pythonにはアスペクト指向ライブラリがあると思いますが、それらを使用している人は誰も知りません。AOPが必要なものの99%は、デコレータと動的オブジェクト変更で実行できるからです。Javaの世界でAspectJが広く使用されていることは、外部ツールで補う必要のあるコアJava言語の欠陥があることを私に示唆しています。
于 2010-09-01T20:26:07.717 に答える
5

Pythonでそれが好きですか?

これは Pythonの一部です。Pythonでそれ好むのはばかげています。

大きなプロジェクトで役に立った例はありますか?

はい。毎日、私は変更を加えることができることを喜んでいます。また、Duck のタイピングのおかげで、それらは適度にローカライズされ、すべての単体テストに合格し、すべての統合テストに合格し、他の場所で中断されるものは何もありません。

これが Java の場合、Java の静的型チェックでまだ許可されているバリエーションを導入できるように、クラスからインターフェイスを引き出すには、無限のリファクタリングが必要になります。

少しエラーが発生しませんか?

静的型付けにすぎません。簡単な単体テストで、オブジェクトが期待される機能に準拠していることを確認します。

(a) コンパイル時のチェックに合格し、(b) 実行時にひどくクラッシュするクラスを Java で作成するのは簡単です。キャストはこれを行う良い方法です。クラスの意図を満たさないことはよくあることです。クラスはコンパイルできても動作しませ

于 2010-09-01T20:03:10.297 に答える
2

多くのパターン(GoFなど)は不要であるか、機能的なフレーバーを備えた動的型付け言語でより少ない労力で実装できます。実際、多くのパターンがpythonに「組み込まれている」ので、短くて「pythonic」なコードを書くと、すべての利点を無料で得ることができます。Iterator、Observer、Strategy、Factory Method、Abstract Factory、およびJavaやC++で一般的なその他のパタ​​ーンは必要ありません。

これは、書くコードが少なくなり、(はるかに重要な)読み取り、理解、サポートするコードが少なくなることを意味します。これがPythonのような言語の主な利点だと思います。そして私の意見では、これは静的型付けがないことをはるかに上回っています。タイプ関連のエラーはPythonコードではあまり発生せず、単純な機能テストで簡単にキャッチできます(このようなテストは、JavaよりもPythonで作成する方が確実です)。

于 2010-09-01T20:33:17.767 に答える
0

あなたが Java の世界の出身であるため、Java の型システムを満足させるためだけに、書かなければならないものをすべて書かなくてもよいのは素晴らしいことだというのが明白な答えです。

もちろん、静的に型チェックされた言語は他にもありますが、Java で書かなければならないすべてのものを書く必要はありません。

C# でさえ、ローカル メソッド変数の型推論を行います!

また、Java が提供するよりも多くのコンパイル時エラー チェックを提供する、静的に型チェックされた言語が他にもあります。

(Python の動的型付けの何がそんなに優れているのか? に対するあまり明白でない答えを理解するには、おそらく Python をもっと理解する必要があります。)

于 2010-09-01T19:24:57.160 に答える
0

それはあなたの心の負荷です。赤の色は、"Red" (定数) として "255, 0, 0" (タプル) または "#FF0000" (文字列) と考えることができます: 3 つの異なる形式で、3 つの異なる型または複雑なルックアップが必要になります。および Java の変換メソッド。

コードが簡単になります。

于 2010-09-01T19:16:20.267 に答える
0

たとえば、整数だけでなく、文字列、リスト、辞書などを渡すことができる関数を作成でき、それらすべてを適切な方法で透過的に処理できます (または例外がスローされる場合)。タイプを処理できません)。他の言語でもそのようなことを行うことができますが、通常、ポインター、参照、型キャストなどを (ab) 使用する必要があり、プログラミング エラーの穴が開いてしまいます。

于 2010-09-01T19:19:29.810 に答える