web-dev-qa-db-ja.com

大規模な開発にPythonを使用するにはどうすればよいですか?

Python=)で大規模な開発について、特に大規模なコードベースをどのように維持するかについて知りたいと思います。

  • メソッドのシグニチャに非互換性の変更を加える場合、そのメソッドが呼び出されているすべての場所をどのように見つけますか。 C++/Javaではコンパイラがそれを見つけてくれますが、Pythonではどのように行いますか?

  • コードの奥深くで変更を加える場合、ルックアップする静的タイプがないため、インスタンスが提供する操作をどのように見つけるのですか?

  • 入力ミス(タイプミス)をどのように処理/防止しますか?

  • UnitTestは静的型チェックの代わりに使用されますか?

ご想像のとおり、私はほとんど静的型付け言語(C++/Java)でのみ作業しましたが、より大きなプログラムでPython)を試してみたいと思います。しかし、非常に悪い経験がありました。ずっと前に、動的に型付けされたクリッパー(dBase)言語で。

58
user31157

誰もpychecker、pylint、および類似のツールを指摘しなかったので、私は次のようにします。静的に型付けされた言語-しかし、そのような言語のそのようなコンパイラーも見つけることができない問題を見つけることができます。

Python(および動的に型指定された言語)は、発生する可能性のあるエラーと、それらを検出して修正する方法の点で根本的に異なります。それには明確な欠点と利点がありますが、多くの人(私を含む)は、Pythonの場合、コードの記述のしやすさ(および構造的に健全にすることのしやすさ)とコードの変更のしやすさなし壊れていると主張しますAPIの互換性(新しいオプションの引数を追加し、同じメソッドと属性のセットを持つ異なるオブジェクトを提供する)は、大規模なコードベースに最適です。

22
Thomas Wouters

ドライバーをハンマーとして使用しないでください

Pythonは静的に型付けされた言語ではないため、そのように使用しないでください。

特定のツールを使用するときは、それが構築されたものに使用します。 Pythonの場合、次のことを意味します。

  • ダックタイピング:タイプチェックなし。重要なのは行動だけです。したがって、この機能を使用するようにコードを設計する必要があります。優れた設計とは、一般的なシグネチャ、コンポーネント間の依存関係、高い抽象化レベルを意味します。したがって、何かを変更した場合でも、コードの残りの部分を変更する必要はありません。 Pythonは、それが何のために構築されたのかについても文句を言いません。タイプは問題ではありません。

  • 巨大な標準ライブラリ。自分でコーディングしていない標準機能を使用する場合は、プログラム内のすべての呼び出しを変更する必要はありません。そしてPythonバッテリーが含まれています。私は毎日それらを発見しています。私が始めてみんなのように既存のものを書き直そうとしたときに使用できるモジュールの数がわかりませんでした。大丈夫です、あなた最初からうまくいくことはできません。

Java、C++、Python、PHP、Erlangなどを同じように書くことはありません。それらは、非常に多くの異なる言語のそれぞれのための余地がある理由であり、同じことをしません。

ユニットテストは代替ではありません

ユニットテストは、任意の言語で実行する必要があります。最も有名な単体テストライブラリ( JUnit )は、Java世界からのものです!

これは型とは何の関係もありません。もう一度、動作を確認します。回帰の問題を回避します。顧客が軌道に乗っていることを確認します。

大規模プロジェクトのPython

言語、ライブラリ、フレームワークは拡張性がありません。アーキテクチャはそうです。

堅固なアーキテクチャを設計する場合、それを迅速に進化させることができれば、拡張性があります。単体テストは、自動コードチェックにも役立ちます。しかし、それらは単なるセーフティネットです。そして小さなもの。

Pythonは、いくつかの優れたプラクティスを実施し、多くの通常のデザインパターンが組み込まれているため、大規模なプロジェクトに特に適しています。しかし、繰り返しになりますが、設計されていない目的には使用しないでください。例:PythonはCPUを集中的に使用するタスク用のテクノロジーではありません。

巨大なプロジェクトでは、とにかくいくつかの異なるテクノロジーを使用する可能性があります。 [〜#〜] sgbd [〜#〜] (フランス語 [〜#〜] dbms [〜#〜] )およびテンプレート言語として、またはその他。 Pythonも例外ではありません。

高速にする必要があるコードの部分には、おそらくC/C++を使用することをお勧めします。またはJava Tomcat 環境に適合します。わからない、気にしないでください。Pythonこれらでうまく機能します。

結論として

私の答えは少し失礼に感じるかもしれませんが、誤解しないでください。これは非常に良い質問です。

多くの人が古い習慣でPythonに来ます。私は、PythonのようにJavaをコーディングしようとして、自分自身を台無しにしました。 。

Pythonをプレイしたことがある、またはプレイしたい場合は、すばらしいです。それは素晴らしいツールです。しかし、実際には単なるツールです。

62
e-satis

オープンソースのpython "GuitarHero"クローンである "Frets OnFire"を変更した経験があります。

私が見るように、pythonは本当に大規模なプロジェクトにはあまり適していません。

互換性のない型の割り当てに関連する問題のデバッグに開発時間の大部分を費やしていることに気付きました。静的型付き言語は、コンパイル時に問題なく明らかになります。また、型は実行時に決定されるため、現在見ているパラメーターの型がわからないため、既存のコードを理解しようとするのは難しくなります。

それに加えて、__getattr__組み込み関数で名前文字列を使用して関数を呼び出すことは、他のプログラミング言語よりも一般的にPythonで一般的です。したがって、呼び出しグラフを特定の関数はやや難しいです(ただし、静的に型指定された言語でも、その名前で関数を呼び出すことができます)。

Pythonは、小規模ソフトウェア、迅速なプロトタイプ開発、および既存のプログラムの接着で本当に優れていると思いますが、大規模ソフトウェアプロジェクトには使用しません。本当の問題であり、私の意見ではpythonは比較的弱いです。

37
rony l

Pythonでかなり大規模なシステムを維持するのに役立ったいくつかの項目があります。

  • コードをレイヤーで構造化します。つまり、個別のビジネスロジック、プレゼンテーションロジック、および永続性レイヤーです。これらのレイヤーの定義に少し時間をかけ、プロジェクトの全員が参加するようにします。大規模なシステムでは、特定の開発方法を強制するフレームワークを作成することも重要です。

  • テストは重要です。単体テストを使用しないと、他の言語よりも数倍速く管理できないコードベースになってしまう可能性があります。多くの場合、単体テストでは不十分であることに注意してください。大きな変更があった場合は、すぐに実行できる統合/受け入れテストをいくつか用意してください。

  • Fail Fast 原則を使用します。コードが脆弱であると思われる場合のアサーションを追加します。

  • 問題にすばやく移動するのに役立つ標準のロギング/エラー処理を用意する

  • タイプアヘッドのpyLint/Checker統合を提供するIDE(pyDevは私のために機能します)を使用して、一般的なタイプミスをすぐに検出し、いくつかのコーディング標準を促進するのに役立ちます

  • インポートには注意が必要です。ximport *を実行したり、を使用せずに相対インポートを実行したりしないでください。

  • リファクタリングを実行します。多くの場合、正規表現を使用した検索/置換ツールだけで、移動メソッド/クラスタイプのリファクタリングを実行できます。

16
Kozyarchuk

私の0.10ユーロ:

私はいくつかのpython application in 'production'-state。当社ではJava、c ++およびpythonを使用しています。私たちはEclipse ide(pythonのpydev)で開発しています

ユニットテストは問題の重要な解決策です。(c ++およびJavaの場合も)

安全性の低い「動的型付け」の世界では、コードの品質についての不注意が少なくなります。

BY THE WAY

大規模な開発は、単一の言語を使用することを意味するものではありません。

大規模な開発では、多くの場合問題に固有の少数の言語が使用されます。

だから私はthe-hammer-problem:-)に同意します


PS: static-typing&python

16
Blauohr

メソッドのシグネチャに対する互換性のない変更。これはPython JavaおよびC++の場合ほど発生しません。 。

Pythonには、オプションの引数、デフォルト値、およびメソッドシグネチャの定義におけるはるかに高い柔軟性があります。また、ダックタイピングは、たとえば、ソフトウェアの大幅な変更の一環として、あるクラスからインターフェイスに切り替える必要がないことを意味します。物事はそれほど複雑ではありません。

そのメソッドが呼び出されているすべての場所をどのように見つけますか? grepは動的言語で機能します。メソッドが使用されているすべての場所を知る必要がある場合は、grep(または同等のIDEサポート検索)が最適です。

検索する静的なタイプがないため、インスタンスが提供するオペレーションをどのようにして見つけるのですか?

a。ソースを見てください。対処するオブジェクトライブラリやjarファイルのJava/C++の問題はありません。これらの言語に必要なすべての手の込んだ支援やツールは必要ありません。

b。 IDEは、多くの一般的な状況で署名情報を提供できます。IDEの推論能力を簡単に打ち負かすことができます。その場合は、実行していることを確認して、意味があることを確認する必要があります。 。IDEでタイプ情報を推論できない場合は、動的すぎる可能性があります。

c。 Pythonでは、多くの場合、インタラクティブなインタープリターを使用します。 JavaやC++とは異なり、インスタンスを直接かつインタラクティブに探索できます。高度なIDEは必要ありません。

例:

  >>> x= SomeClass()
  >>> dir(x)

入力エラーをどのように処理/防止しますか?静的言語と同じです:それらを防止しません。あなたはそれらを見つけて修正します。 Javaは、特定のクラスのタイプミスしか見つけることができません。2つの類似したクラス名または変数名がある場合、静的な型チェックを行っても、深刻な問題が発生する可能性があります。

例:

class MyClass { }
class MyClassx extends MyClass { }

これら2つのクラス名のタイプミスは、混乱を引き起こす可能性があります。 [「しかし、私はJavaで自分をそのような立場に置くことはないだろう」と人々は言う。同意した。私もPythonでその立場に立つつもりはありません。大きく異なるクラスを作成し、それらを誤用すると早期に失敗します。]

nitTestは静的型チェックの代わりに使用されますか?他の観点は次のとおりです。静的型チェックは、明確でシンプルな設計の代わりになります。

私は、アプリケーションが機能する理由がわからないプログラマーと協力してきました。彼らは物事がコンパイルされなかった理由を理解できませんでした。抽象スーパークラスとインターフェースの違いを知りませんでした。また、場所を変更すると、別のJARファイル内の他のモジュールがクラッシュする理由を理解できませんでした。静的な型チェックは、欠陥のある設計に対する誤った信頼を与えました。

動的言語を使用すると、プログラムを単純にすることができます。単純性は静的型チェックの代用です。明快さは静的型チェックの代わりです。

8
S.Lott

私の一般的な経験則は、ミッションクリティカルではない小さなプロジェクトには動的言語を使用し、大きなプロジェクトには静的に型付けされた言語を使用することです。 pythonなどの動的言語で記述されたコードは、より速く「絡み合う」ことがわかりました。これは、動的言語でコードを記述する方がはるかに高速であり、ショートカットにつながり、より悪いためです少なくとも私の場合はデザインです。これは、PythonにはないJavaを使用するときに、すばやく簡単にリファクタリングできるIntelliJがあるためです。

それに対する通常の答えは、テストテストテストです。特に新しいバージョンがオンラインになる前に、広範な単体テストスイートを用意し、それを頻繁に実行する必要があります。

動的に型付けされた言語の支持者は、静的に型付けされた言語であっても、型システムの大まかな規則への準拠は潜在的にうまくいかない可能性のあるもののごく一部しかカバーしないため、とにかくテストする必要があると主張します。

2
fgg