高品質のPythonプログラムの作成(3)基本構文

この一連の記事は、「Pythonプログラムを改善するための高品質なコード91の提案を書く」の本質の要約です。

モジュールのインポートについて

外部モジュールのPythonを導入する3つの方法:import文、from ... import ...および__import__機能。最初の2つはより一般的です。

使用時にはimport、それに注意を払う必要があります:

  • 優先順位の使用import Aまたはimport A as a
  • 控えめに使う from A import B
  • 使用しないようにしてください from A import *

以下のためのfrom a import ...制御されていない使用の問題は、持参する場合は、:

  • 名前空間の競合
  • ネストされたループのインポートの問題(2つのファイルが互いの変数または関数またはクラスをインポートする)

i += 1 等しくない ++i

Pythonインタプリタがあろう++iものとして解釈される+(+i)場合、+記号の正の数を表します。以下のためには--i似ています。

したがって、我々は理解しなければならない++i文法レベルPythonは有効ですが、通常の意味ではないインクリメント演算子。

使用するwith自動シャットリソースを

開いたファイルはシステムリソースを占有するだけでなく、他のプログラムやプロセスの動作に影響を与える可能性があるため、ファイル操作が完了したらすぐにそれらを閉じる必要があります。また、ユーザーの期待と実際の操作結果との不一致が発生する場合もあります。

Pythonは、構文を伴うwithステートメントを提供します。

with 表达式 [as 目标]:
    代码块

withステートメントはネストをサポートし、複数のwith句をサポートし、それらは相互に変換できます。with expr1 as e1, expr2 as e2 次のネストされたフォームと同等です。

with expr1 as e1:
    with expr2 as e2:

使用else句を簡素化ループ(例外処理)

サイクルでは、else句は、サイクルによってか暗示を提供breakサイクル判決文の終わりに起因します。例:

# 以下两段代码等价
# 借助了一个标志量 found 来判断循环结束是不是由 break 语句引起的。
def print_prime(n):
    for i in range(2, n):
        found = True
        for j in range(2, i):
            if i % j == 0:
                found = False
                break
        if found:
            print("{} is a prime number".format(i))

def print_prime2(n):
    for i in range(2, n):
        for j in range(2, i):
            if i % j == 0:
                break
        else:
            print("{} is a prime number".format(i))

ときサイクル「自然」終了(ループ条件が偽である)else句は、一度実行され、サイクルがあるときにbreak、割り込み文、else句は実行できません。

そして、for文と類似whileelse句の意味は同じである:elseブロックが満たされていない通常のサイクルとサイクル条件の終了時に実行されます。

例外処理のいくつかの基本原則に従います

Pythonは、一般的に例外処理の構文で使用されるtry、、 、except 彼らは様々な組み合わせを持つことができます。構文は次のとおりです。elsefinally

# Run this main action first
try:
    <statements>

# 当 try 中发生 name1 的异常时,进行处理
except <name1>:
    <statements>

# 当 try 中发生 name2 或 name3 中的某一个异常时
except (name2, name3):
    <statements>

# 当 try 中发生 name4 的异常时处理,并获取对应实例
except <name4> as <data>:
    <statements>

# 其他异常时,进行处理
except:
    <statements>

# 没有异常时,执行
else:
    <statements>

# 无论有没有异常,都执行
finally:
    <statements>

例外処理には通常、次の基本原則が必要です。

  • お勧めできませんtryあまりにも多くのコードを配置試行に多くのコードを配置することによって引き起こされる問題は、プログラムで例外がスローされると、見つけにくくなり、デバッグと修復が不便になるため、例外をスローする可能性のあるステートメントブロックの前にのみ配置するようにしてください。ステートメントを試してください。
  • 慎重な使用別々のexcept文は、すべての例外を処理する、それが特定の例外を見つけることが最善ですまた、使用することを推奨していないexcept Exceptionか、except StandardErrorキャッチ例外に。あなたが使用する必要がある場合、それを使用するのが最適であるraise上位層に渡された例外をスローするステートメントを。
  • 例外のキャッチの順序に注意を払い、適切なレベルで例外を処理します。
    • ユーザーは、組み込みの例外から継承して独自の例外クラスを作成することもできます。これにより、組み込みクラスの継承構造が拡張されます。この場合、例外がキャプチャされる順序は非常に重要です。より正確には、エラーの原因を見つけるために、推奨されるアプローチは、前に中性子の異常を継承することでexcept、後続の例外でthrowステートメント、親クラスexceptスロー声明。この理由は、ときにあるtryブロックが発生した例外を有する、インタプリタに応じてexcept即座に例外を処理容易最初の試合で宣言の順序と一致します。
    • 例外をキャッチする順序は非常に重要です。同時に、例外は適切な場所で処理する必要があります。1つの原則は、例外をキャッチした場所で処理できる場合は、タイムリーに処理することです。上位層に渡す場合は、異常がなくなった場合に注意する必要があり、パラメータなしでレイズを使用して渡すことができます。
  • よりわかりやすい例外情報を使用し、例外パラメーターの仕様に従ってください。一般的に、異常なリーダーには、ソフトウェアを使用するものとソフトウェアを開発するものの2種類があります。

最終的に可能なトラップを回避

かかわらずtry例外が声明を投げているかどうか、finally文は常に実行されます。この機能のため、finallyクリーンアップ作業を行うためにステートメントがよく使用されます。
しかし、使用finally時には、トラップ特に注意する必要があります。

  • ときにtry例外がブロック内で発生した場合、exceptステートメントを処理する対応する例外を見つけることができません、例外は一時とき、アップ保存されるfinally時間が終了すると、一時的な保存に例外を再びスローされますが、場合finally文が生成されます新しい例外または実行returnbreak、文、一時的に保存された例外が異常なシールドで、その結果、失われます。
  • 実際のアプリケーション開発プロセスでは、推奨されていませんfinally使用するreturnこのアプローチは誤解をもたらすだけでなく、非常に重大なミスにつながる可能性があり、リターンに声明を。

どれも深く理解し、オブジェクトが空かどうかを正しく判断する

Pythonの次のデータは空として扱われます。

  • 一定 None
  • 一定 False
  • このようなゼロ値型のいずれかの形態、00L0.00j
  • 以下のような空のシーケンス、''()[]
  • 次のような空の辞書 {}
  • ユーザ定義のクラスが定義されている場合__nonzero__()__len__()方法、及び方法は、整数を返し0又はFalse時間。
if list1 # value is not empty
    Do something
else: # value is empty
    Do some other thing
  • これは、実行時に内部メソッドを呼び出して__nonzero__()変数を決定するためにlist1nullであり、結果を返します。

注:__nonzero__()メソッド-この内部メソッドは、独自のオブジェクトのnull値をテストするために使用され、0/1またはTrue / Falseを返します。

  • オブジェクトは、メソッドを定義しない場合、Pythonは取得__len__()メソッド呼び出しの結果を判断します。__len__()戻り値0は空を意味します。クラスが定義されていない場合は__len__()方法が定義されていない__nonzero__()方法を決意結果が真である場合、クラスの例が使用されます。

文字列の形式を使用してみてください.formatではなく、%

利用するように推奨format代わりの方法%文字列形式、理由オペレーター:

  • format使用に比べて実施例%より柔軟なオペレータ。使用format時にモード、および順序は、必ずしも同一の書式設定パラメータではありません

  • format メソッドはパラメータとして簡単に渡すことができます

    weather = [("Monday", "rain"), ("Tuesday", "sunny"), ("Wednesday", "sunny"), ("Thursday", "rain"), ("Friday", "cloudy")]
    formatter = "Weather of '{0[0]}' is '{0[1]}'".format
    for item in map(formatter, weather):
        print(item)
    
  • %最終的には.formatに置き換えられます。公式Pythonドキュメントによると、理由は残る%オペレータは、下位互換性を維持することです

  • %以下のために、いくつかの特別なケースでの方法を使用する場合には、特別な注意が必要とされている%文字自体がタプルであるならば、あなたが使用する必要があり、このフォームの直接文字書式%を使用して(itemname,)、回避エラーするためにこのフォームをカンマに注意してください。

可変オブジェクトと不変オブジェクトを別々に扱う

Pythonのすべてがオブジェクトであり、オブジェクトは、値を変更できるかどうかに応じて可変オブジェクト不変オブジェクトに分けられます

  • 不変オブジェクト

    • 数字
    • 文字列
    • タプル
  • 可変オブジェクト

    • 辞書
    • リスト
    • バイト配列

関数のデフォルトパラメータとして変数オブジェクト使用する場合は特に注意しください。変数オブジェクトを変更すると、元のオブジェクトに直接影響します。

最善の方法は、渡されたNoneオブジェクトを作成するときに、デフォルトのパラメータは、動的に生成された変更可能なオブジェクトとして。

  • 可変オブジェクトの場合、スライス操作は浅いコピーと同等です。

  • 不変オブジェクトの場合、それに関連する操作を実行しても、Pythonは実際には元の値を保持し、新しいオブジェクトを再作成するため、文字列オブジェクトをインデックスで割り当てることはできません。同時に2つのオブジェクトがある場合文字列オブジェクトを指す場合、オブジェクトの1つに対する操作は他のオブジェクトには影響しません。

パラメータを渡す関数は値でも参照でもありません

Pythonの関数にパラメーターを渡す方法は、値でも参照でもありません

これは、正しい名前であるべき転送オブジェクト(オブジェクトによる呼び出し)または基準質量オブジェクト(コール・バイ・オブジェクト参照 )。

関数パラメーターは、渡すプロセスでオブジェクト全体を渡します。

  • 以下のために可変オブジェクト:その変形は、発呼者と被呼者との間でこのオブジェクトを共有し、内部および外部関数に表示され
  • 不変オブジェクト:実際には変更されないので、そのため、多くの場合、新しいオブジェクトを作成することによって変更された後、達成するために割り当てられ、

注意して可変長パラメーターを使用する

*args, **kwargs次の理由により、可変長パラメーターを注意して使用してください

  • 使用するには柔軟性が高すぎます。可変長パラメーターは、この関数のシグニチャーが十分に明確ではないことを意味し、呼び出しには多くの方法があります。さらに、可変長パラメーターはプログラムの堅牢性を損なう可能性があります。
  • 関数のパラメータリストが非常に長い場合に使用しても、*argsおよび**kwargs関数の定義が、通常この機能を簡素化するために、より良い実装を持つことができ、それが再構築されなければなりません。たとえば、タプルと辞書を直接渡すことができます。

可変長パラメーターは、以下の状況での使用に適しています。

  • 関数にデコレーターを追加する
  • パラメーターの数が不明な場合は、可変長パラメーターの使用を検討してください
  • 関数のポリモーフィズムを実装するため、または継承の場合にサブクラスが親クラスのいくつかのメソッドを呼び出す必要がある場合に使用されます

深い理解str()repr()区別

関数str()repr()Pythonはオブジェクト文字列に変換することができ、両方を使用して出力が非常に類似しています。以下の違いがあります。

  • 2つの目標は異なります。

    • str() 主にユーザー向けで、その目的は読みやすさです。戻りフォームは、使いやすさと読みやすさを備えた文字列型です。
    • そしてrepr()開発者のために、精度の目的は、Pythonインタプリタの内部の意味を示す戻り値は、デバッグのために使用さ
  • デフォルトは、入力に直接インタープリタで呼ばれているrepr()機能、およびprintその後、呼び出しstr()機能を

  • repr()戻り値は、一般的にできるeval()オブジェクトを復元するために機能します。通常、次の方程式があります。obj == eval(repr(obj))

  • 一般的に、クラスが定義されなければならない__repr__()方法、および__str__()方法を可読性が精度よりも重要であるとして、任意であり定義されたと考えるべきである__str__()方法。クラスが定義されていない場合__str__()、デフォルト使用して、メソッドを__repr__()オブジェクトの文字列表現を返すために、プロセスの結果を。ユーザが達成する__repr__()時間法を、戻り値を使用することができることを保証することが望ましいeval()オブジェクトが再び復元される方法。

静的メソッドとクラスメソッドの該当するシナリオを区別する

静的メソッド:

class C(object):
    @staticmethod
    def f(arg1, arg2, ...):

クラスメソッド:

class C(object):
    @classmethod
    def f(cls, arg1, arg2, ...):

类名.方法名またはからアクセスできます实例.方法名

その中でも、静的メソッドには、バインディング、バインド解除、暗黙的なパラメーター、その他のルールなど、従来のメソッドの特別な動作はありません。クラスメソッドの呼び出しは、クラス自体を暗黙的なパラメーターとして使用しますが、呼び出し自体はパラメーターを明示的に提供する必要はありません。

クラスメソッド

  • 呼び出し時に明示的なclsの宣言はありませんが、実際にはクラス自体が非表示パラメーターとして渡されます
  • クラスメソッドは、基本クラスまたはサブクラスのどちらを介して呼び出されるかを決定できます。
  • クラスメソッドがサブクラスによって呼び出されると、基本クラスの代わりにサブクラスの属性を返すことができます
  • クラスメソッドがサブクラスによって呼び出されると、サブクラスの他のクラスメソッドを呼び出すことができます

静的メソッド

  • 特定のインスタンスにも特定のクラスにも関連していない
  • クラスで静的メソッドが定義されている理由は、コードをより効率的に編成できるため、関連するコードの垂直距離が近くなり、コードの保守性が向上するためです。

この記事は最初に公開アカウントで公開されました[Pythonとアルゴリズムへの道]

おすすめ

転載: www.cnblogs.com/monteyang/p/12728729.html