Pythonプログラムの改善の提案

4200 ワード

三元オペレータ:C言語では、三元オペレータがC ? X : Yであることはよく知られています.人々の強い要求の下で、python 2.5以降の3元オペレータはX if C else Yに等価である.
いつ断言を使うべきですか.断言の基本構文は、assert expression1 ["," expression2]でexpression 1の値を計算するとTrueまたはFalseが返され、値がFalseの場合AssertErrorが発生しますが、expression 2はオプションで、具体的な異常情報を表示するのによく使用されます.断言には代価があり、パフォーマンスに一定の影響を及ぼすが、pythonはデバッグとパブリッシュモードの違いを厳密に定義していない.通常、断言を無効にする方法は、スクリプトを実行するときに-Oフラグを付けることであり、バイトコードを最適化するのではなく、断言に関連する文を無視することに影響を与える.断言は,ユーザ定義の制約をキャプチャするために用いられ,プログラム自体のエラーをキャプチャするために用いられるものではない.
  • は、通常の論理が到達できない場所または通常の場合に常に真の場合に使用されるべきだと断言する.
  • 異常処理は断言を使用しないでください.
  • ユーザー入力を断言でチェックしないでください.
  • 関数呼び出し後、戻り値が妥当であるかどうかを決定する必要がある場合は、断言を使用します.
  • 条件がビジネスロジック継続の前提条件である場合、断言を使用することができる.

  • 私は最近、爬虫類コードで何回か断言を使用しました.断言を使用するのは、プログラム自体が記録したページ数が爬虫類が実行したページ数と同じであることを保証するためです.そうしないと、データを格納する際にエラーが発生します.
    データ交換値の場合、中間変数x,y = y,xを使用することは推奨されません.この方法は、より良い性能を有します.
    合理的なパッケージ階層を構築してmoduleを管理するのは本質的にpythonファイルごとにモジュールですが、大きなプロジェクトですべてのpythonファイルを1つのディレクトリの下に置くのは良い方法ではありません.パッケージパッケージでモジュールを管理する必要があります.__init__.pyのいくつかの役割:
    Package/ __init__.py
      Module1.py
      Module2.py
      Subpackage/ __init__.py
            Module1.py
            Module2.py
  • パッケージと一般ディレクトリを区別する
  • Packageパッケージの__init__.pyに:from Module1 import Test文を追加すると、from Package import Testを直接使用してクラスTest
  • をインポートできます.
  • __init__.pyが空の場合、from Package import *文を使用してパッケージPackage内のすべてのモジュールを現在のネーミングスペースにインポートしようとすると失敗します.__init__.pyファイルのみが実行されます.そのため、__init__.pyファイルを修正する必要があります.__init__.pyファイルに追加すると:
  • __all__ = ['Module1','Module2','Subpackage']これにより、from Package import *文を使用して、パケットPackage内のすべてのモジュールを現在のネーミングスペースにインポートできます.
    withを使用してリソースwith文を自動的に閉じると、コードブロックの実行が完了した後、コードブロックに入ったときのフィールドを復元できます.ファイル管理時にwithを使用すると、ファイルが正常に閉じられることが保証されます.
    Noneの特殊性Noneとして付与変数はすべて等しく、Noneと他のNone以外のオブジェクトとの比較結果はFalseである.
    文字列の接続、特に大規模な文字列の処理は、+ではなくjoinを優先的に使用する必要があります.S1+S2+S3+..の場合、+操作を1回実行すると、メモリに新しいメモリが申請され、前回の操作の結果と今回の操作の右の操作数がメモリにコピーされます.N文字列接続では、N-1個の中間結果が生成され、中間結果が生成されるたびにメモリが申請され、コピーされ、合計N-1個のメモリが申請され、効率に深刻な影響を及ぼします.時間的複雑度はOに近い(n^2).一方、join()メソッドを使用して文字列を接続すると、まず申請が必要な合計メモリ領域が計算され、必要なメモリが一度に申請され、文字シーケンスの各要素がメモリにコピーされます.時間的複雑度はO(n)であった.
    pythonにはすべてオブジェクトがあり、各オブジェクトには一意のidがあります.関数パラメータは、C/C++ではなく、値ではなく、参照ではありません.
    a = 5;
    b = a;
    b = 7;

    メモリにメモリを申請し、aの値をメモリにコピーし、b=7を実行するとbに対応する値を5から7に変更します.pythonの場合、割り当てはコピーではなく、b=aはaとbが同じオブジェクトを参照するようにします.b=7は、bをオブジェクト7に向ける.python関数パラメータは、値が伝達されるか、参照が伝達されるかではなく、実際には、伝達オブジェクトまたは伝達オブジェクトの参照です.可変オブジェクトの変更は、関数の外部および内部で表示され、呼び出し者と被呼び出し者の間でこのオブジェクトが共有されます.可変オブジェクトの場合、実際に変更することはできません.なぜなら、変更は、新しいオブジェクトを生成して値を割り当てることによって実現されることが多いからです.
    デフォルトパラメータの潜在的な問題を警戒
    def python          ,      def ,         ,      .func_defaults   。  
      Python           ,                 。
    def appendtest(newitem,lista=[]):
        print(id(lista))
        lista.append(newitem)
        print(id(lista))
        return lista
    
    >>> appendtest(1)
    12345
    12345
    [1]
    >>> appendtest('a')
    12345
    12345
    [1,'a']

    PS:この属性を使って、あるメソッドが呼び出された回数を統計することができます.デフォルトのパラメータが指すオブジェクトをすべての関数呼び出しで共有するのではなく、関数呼び出し中に動的に生成する場合は、定義時にNoneオブジェクトをプレースホルダとして使用します.
    def appendtest(newitem,lista=None):
        print(id(lista))
        lista.append(newitem)
        print(id(lista))
        return lista

    str()とrepr()の違い:ターゲットが異なる:str()はユーザー向け、repr()は解釈器と開発者文字列向けのいくつかのテクニック:
  • pythonが閉じていないカッコに遭遇すると、複数行のコードが自動的に1行に結合され、隣接する2つの文字列の字面量が結合されます.
  • s = ('SELECT * '
        'FROM atable '
        'WHERE afirld="value"')
    print(s)
    >>> SELECT * FROM atable WHERE afirld="value"
  • strのいくつかの方法strの方法は多くて、いくつかの面白いことを言います:
  • count()は、replaceメソッドを呼び出すときに使用できるサブストリングが文字列に現れる回数を検索し、一括で置き換えることができます.replace(old,new[,count])は、文字列の一部のサブ列を置換するために使用され、countパラメータを指定すると、countを最大数回置換し、指定しないとすべて置換します.
    参考資料:「高品質コードの作成:Pythonプログラムの改善に関する91の提案」