
Pythonプログラミング言語の構文は、Pythonプログラムがどのように記述され、実行システムと人間の両方によって解釈されるかを定義する一連の規則です。Python言語はPerl、C、Javaと多くの類似点がありますが、明確な違いもいくつかあります。Pythonは、構造化プログラミング、オブジェクト指向プログラミング、関数型プログラミングなど、複数のプログラミングパラダイムをサポートし、動的な型システムと自動メモリ管理を備えています。
Pythonの構文はシンプルで一貫性があり、「物事を行うには、明白な方法が一つ、できれば一つだけ存在するべきだ」という原則に基づいています。この言語には、組み込みのデータ型と構造体、制御フロー機構、第一級関数、モジュールが組み込まれており、コードの再利用性と整理性が向上しています。また、Pythonは他の言語で句読点を使用する箇所で英語のキーワードを使用しており、視覚的にすっきりとしたレイアウトに貢献しています。
Pythonは例外処理による堅牢なエラー処理機能を備えており、効率的な問題解決のために標準ライブラリにデバッガも含まれています。読みやすさと使いやすさを重視したPythonの構文は、初心者からプロまで幅広い層に人気があります。
Python は、非常に読みやすい言語として設計されました。[ 1 ]視覚的なレイアウトは比較的すっきりとしており、他の言語では句読点を使用する箇所で英語のキーワードを頻繁に使用しています。Python は、構文の設計においてシンプルかつ一貫性を保つことを目指しており、これは「Python の禅」にある「物事を行うには、明白な方法が 1 つ、できれば 1 つだけあるべきだ」というモットーに集約されています。[ 2 ]
このモットーは、 PerlやRubyのモットーである「物事には複数のやり方がある」とは意図的に対立するものである。
Python 3 には 35 個のキーワードまたは予約語があり、これらは識別子として使用できません。[ 3 ] [ 4 ]
さらに、Python 3 には、Python 3.12 で追加された4 つのソフトキーワードもあります。通常のハードキーワードとは異なり、ソフトキーワードは、キーワードとして解釈することが構文的に意味を持つ限られたコンテキストでのみ予約語となります。これらの単語は他の場所で識別子として使用できます。つまり、matchとcase は関数と変数の有効な名前です。[ 6 ] [ 7 ]type
関数アノテーション(型ヒント)は PEP 3107 で定義されています。[ 8 ]これにより、関数の引数と戻り値にデータを付加できます。アノテーションの行為は言語では定義されておらず、サードパーティのフレームワークに委ねられています。たとえば、静的型付けを処理するライブラリを作成できます。[ 8 ]
def haul ( item : Haulable , * vargs : PackAnimal ) -> Distance : # ここに実装を記述Pythonでは注釈は必須ではありませんが、この記事では分かりやすさを向上させるために注釈を使用します。
Python では、コードはモジュールと呼ばれるファイルに整理され、名前空間は個々のモジュールによって定義されます。モジュールは階層的なパッケージに含めることができるため、名前空間も階層的になります。[ 9 ] [ 10 ] 一般的に、モジュールがインポートされると、モジュール内で定義されている名前はそのモジュールの名前空間を介して定義され、呼び出し元のモジュールからは完全修飾名を使用してアクセスされます。
# ModuleA は func1() と func2() という 2 つの関数と Class1 という 1 つのクラスを定義していると仮定しますimport ModuleAModuleA.func1 ( ) ModuleA.func2 ( ) a : ModuleA.Class1 = ModuleA.Class1 ( )このfrom ... import ...ステートメントを使用すると、関連する名前を呼び出し元モジュールの名前空間に直接挿入でき、呼び出し元モジュールからは修飾名なしでそれらの名前にアクセスできます。
# ModuleA は func1() と func2() という 2 つの関数と Class1 という 1 つのクラスを定義していると仮定します。from ModuleA import func1func1 () func2 () # これは未定義の名前として失敗します。完全な名前 ModuleA.func2() も同様です。a : Class1 = Class1 () # これは未定義の名前として失敗します。完全な名前 ModuleA.Class1() も同様です。これは名前を(修飾子なしで)直接インポートするため、警告なしに既存の名前を上書きする可能性があります。
ステートメントの特別な形式は、from ... import *指定されたパッケージで定義されているすべての名前を呼び出し元モジュールの名前空間に直接インポートするものです。この形式のインポートは言語内でサポートされていますが、呼び出し元モジュールの名前空間を汚染し、名前の衝突が発生した場合に既に定義されている名前が上書きされるため、一般的には推奨されません。[ 11 ]ただし、このページでは、コレクション型を参照するために、行from typing import *" が含まれているかのようにコードを示します。
さまざまなインポート文を以下に示します。
# 引数解析モジュールをインポートしますimport argparse # 正規表現モジュールから Pattern クラスをインポートしますfrom re import Pattern # 型付けモジュール内のすべてのシンボルをインポートしますfrom typing import *Pythonのステートメントを使用すると、from importネストされた名前空間など、冗長な名前空間を簡略化できます。
from selenium.webdriver import Firefox from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.remote.webelement import WebElementif __name__ == "__main__" : driver : Firefox = Firefox () element : WebElement = driver . find_element ( By . ID , "myInputField" ) element . send_keys ( f "Hello World { Keys . ENTER } " ) action : ActionChains = ActionChains ( driver ) action . key_down ( Keys . CONTROL ) . send_keys ( "a" ) . key_up ( Keys . CONTROL ) . perform ()Pythonでは、import x as y呼び出し元のモジュールが使用するエイリアスまたは代替名を提供する方法として、以下の機能もサポートしています。
import numpy as np from numpy.typing import NDArray , float32a : NDArray [ float32 ] = np 。オレンジ( 1000 )モジュールがインポートされると、Python インタプリタはまずsys.modulesキャッシュに存在するかどうかを確認し、以前にインポートされていた場合はそれを再利用し、そうでない場合はロードします。ロード時には、 を検索しsys.path、バイトコードにコンパイルするか、その内容を解釈します。モジュールのグローバル スコープ内のすべてのコードが実行されます。ただし、明示的な main 関数を使用することで、この問題を軽減できます。この関数は、ほとんどのコンパイル言語のエントリ ポイントと同様に動作し、以下のようにエントリ ポイント イディオムを使用します。
擬似エントリポイントは、プログラムの実行時__name__に内部変数が設定される__main__が、モジュールとしてインポートされる際には設定されない(その場合はモジュール名に設定される)というイディオムによって作成できます。この構造には多くのバリエーションがあります。[ 12 ] [ 13 ] [ 14 ]
import sysdef main ( argv : list [ str ]) -> int : argc : int = len ( argv ) # argv の長さを取得n : int = int ( argv [ 1 ]) print ( n + 1 ) return 0if __name__ == " __main__ " : sys.exit ( main ( sys.argv ) )このイディオムでは、名前付きエントリポイントへの呼び出しが明示的であり、オペレーティングシステムmainとのやり取り(引数の受け取り、システム終了の呼び出し)はライブラリ呼び出しによって明示的に行われ、最終的にはPythonランタイムによって処理されます。これは、慣例に基づいてランタイムが暗黙的にこれらの処理を行うC言語とは対照的です。
Python は、制御フローブロックを区切るために空白文字を使用します(オフサイド ルールに従います)。Python はこの機能を前身のABCから受け継いでおり、句読点やキーワードの代わりに、インデントを使用してブロックの実行を示します。
いわゆる「自由形式」言語( ALGOLから派生したブロック構造を使用する言語)では、コードブロックは中括弧( )またはキーワードで区切られます。これらの言語のほとんどのコーディング規約では、プログラマーはブロック内のコードをインデントして、周囲のコードと視覚的に区別するのが一般的です。{ }
単一のパラメータ、を受け取り、 パラメータが 0 の場合は という名前の別の関数を呼び出し、それ以外の場合は を引数として を呼び出し、さらに をパラメータとして渡して自身を再帰的に呼び出す再帰 関数は、Python では次のように実装できます。fooxbarbazxx-1
def foo ( x : int ) -> None : if x == 0 : bar () else : baz ( x ) foo ( x - 1 )C言語では次のように記述できます。
void foo ( int x ) { if ( x == 0 ) { bar (); } else { baz ( x ); foo ( x - 1 ); } }インデントが不適切なコードは、コンパイラやインタプリタによる解釈とは異なり、人間が読むと誤って解釈される可能性があります。たとえば、上記の例の最後の行の関数呼び出しが誤って/ブロックのfoo(x - 1)外側にインデントされている場合、次のようになります。ifelse
def foo ( x : int ) -> None : if x == 0 : bar () else : baz ( x ) foo ( x - 1 )xが 0 の場合でも最後の行が常に実行され、無限再帰が発生します。
インデント形式としてスペースとタブ文字の両方が受け入れられ、任意の倍数のスペースを使用できますが、スペースが推奨されています[ 15 ]。また、4つのスペース(上記の例のように)が推奨されており、最も一般的に使用されています[ 16 ] [ 17 ] 。Python 3以降では、スペースとタブを連続する行で混在させることは許可されていません[ 18 ]。これは、多くのテキストエディタがスペースとタブを視覚的に区別しないため、見つけにくいバグが発生する可能性があるためです。
Pythonは動的型付け言語であるため、型情報は変数ではなく値によって保持されます。Pythonのすべての変数はオブジェクトへの参照を保持し、これらの参照が関数に渡されます。Pythonの作成者であるGuido van Rossum氏自身を含め、一部の人々はこのパラメータ渡し方式を「オブジェクト参照による呼び出し」と呼んでいます。オブジェクト参照とは名前を意味し、渡される参照はC/ C++と同様に、同じオブジェクトへの参照のコピーである「エイリアス」です。呼び出された関数内では、エイリアスを使用してオブジェクトの値を変更できます。例:
my_list:list[str]=["a","b","c"]defmy_func(l:list[str])->None:l.append("x")print(l)print(my_func(my_list))# prints ['a', 'b', 'c', 'x']print(my_list)# prints ['a', 'b', 'c', 'x']Function my_func changes the value of my_list with the formal argument l, which is an alias of my_list. However, any attempt to operate (assign a new object reference to) on the alias itself will have no effect on the original object.
my_list:list[str]=["a","b","c"]defmy_func(l:list[str])->None:# l.append("x")l=l+["x"]# a new list created and assigned to l means l is no more alias for my_listprint(l)print(my_func(my_list))# prints ['a', 'b', 'c', 'x']print(my_list)# prints ['a', 'b', 'c']In Python, non-innermost-local and not-declared-global accessible names are all aliases.
Among dynamically-typed languages, Python is moderately type-checked. Implicit conversion is defined for numeric types (as well as Booleans), so one may validly multiply a complex number by an integer (for instance) without explicit casting. However, there is no implicit conversion between, for example, numbers and strings; a string is an invalid argument to a mathematical function expecting a number.
Pythonには幅広い基本データ型があります。従来の整数演算や浮動小数点演算に加え、任意精度演算、複素数、小数も透過的にサポートしています。
Pythonは、多種多様な文字列操作をサポートしています。Pythonの文字列は不変であり、文字の置換などの文字列操作を行うと、新しい文字列が返されます。他のプログラミング言語では、文字列はそのまま変更される場合があります。パフォーマンス上の理由から、文字列を頻繁に変更するプログラムでは、文字配列を必要な場合にのみ結合するなど、特別な手法を用いる必要がある場合があります。
Pythonの非常に便利な機能の一つに、コレクション(またはコンテナ)型の概念があります。一般的に、コレクションとは、他のオブジェクトを簡単に参照またはインデックス付けできる形で格納するオブジェクトのことです。コレクションには、シーケンスとマッピングという2つの基本的な形式があります。
順序付きシーケンシャル型は、リスト(動的配列)、タプル、および文字列です。すべてのシーケンスは位置インデックス(0から長さ-1まで)で指定され、文字列を除くすべてのシーケンスには、同じシーケンス内に複数の型を含む、あらゆる種類のオブジェクトを含めることができます。文字列とタプルはどちらも不変であるため、辞書のキーとして最適です(下記参照)。一方、リストは可変であり、要素は挿入、削除、変更、追加、またはその場でソートできます。
一方、マッピングは、(多くの場合順序付けされていない)型であり、不変のキーのセットを対応する要素に「マッピング」する辞書"toast"の形式で実装されます(数学関数によく似ています)。たとえば、文字列を整数にマッピングする辞書、またはその逆の辞書を定義できます。辞書のキーは、ハッシュ関数42を介して実装されるため、整数や文字列などの不変のPython型である必要があります。これにより検索時間が大幅に短縮されますが、キーは変更されない必要があります。
辞書はPythonの内部構造において中心的な役割を果たしており、すべてのオブジェクトとクラスの中核を成しています。変数名(文字列)と、その名前が参照する値とのマッピングは辞書として格納されます(オブジェクトシステムを参照)。これらの辞書は(オブジェクトの__dict__属性を介して)直接アクセスできるため、 Pythonではメタプログラミングは簡単かつ自然なプロセスとなります。
セットコレクション型は、インデックスがなく順序も付けられていない、重複のないコレクションであり、和集合、積集合、差集合、対称差集合、部分集合のテストなどの集合論的演算を実装します。セットにはとの2種類があり、唯一の違いは が可変で が不変であることです。セット内の要素はハッシュ可能でなければなりません。したがって、たとえば は通常の の要素になり得ますが、その逆は成り立ちません。setfrozensetsetfrozensetfrozensetset
Pythonは、組み込みの包含チェックや汎用的な反復プロトコルなど、コレクションを操作するための豊富な機能も提供しています。
Pythonでは、クラスも含め、すべてがオブジェクトです。クラスはオブジェクトであるため、メタクラスと呼ばれるクラスを持ちます。Pythonは多重継承とミックスインもサポートしています。
この言語は、型とクラスの詳細な内省をサポートしています。型は読み取って比較できます。型はオブジェクトのインスタンスですtype。オブジェクトの属性は辞書として抽出できます。
Pythonでは、特別なメンバ関数を定義することで演算子をオーバーロードできます。たとえば、__add__クラスにという名前のメソッドを定義すると+、そのクラスのオブジェクトに対して演算子を使用できるようになります。
Pythonには様々な種類の文字列リテラルがあります。
文字列を引用するには、シングルクォートまたはダブルクォートのどちらでも使用できます。Unix シェル言語、Perl、またはRubyやGroovyなどの Perl の影響を受けた言語とは異なり、シングルクォートとダブルクォートは同じように機能します。つまり、 $foo式の文字列補間はありません。ただし、補間はさまざまな方法で行うことができます。「f 文字列」(Python 3.6 以降[ 19 ])、メソッドの使用、または古い%文字列フォーマット演算子の使用などです。format
例えば、以下のすべてのPythonステートメント:
print ( f "プリンター{ printer }に{ num }ページを印刷しました" )print ( "プリンター{}に{}ページを印刷しました。 " . format ( num , printer )) print ( "プリンター{1}に{0}ページを印刷しました。 " . format ( num , printer )) print ( "プリンター{b}に{a}ページを印刷しました。 " . format ( a = num , b = printer ))print ( "プリンター%sに%sページを印刷しました" % ( num , printer )) print ( "プリンター%(b)sに%(a)sページを印刷しました" % { "a" : num , "b" : printer })Perlのステートメントと同等です。
print "プリンター $printer に $num ページを印刷しました\n"彼らは変数とを使用して文字列を構築しnumますprinter。
また、複数行の文字列もあり、それは一連の 3 つのシングルクォートまたはダブルクォートで始まり、3 つのシングルクォートまたはダブルクォートで終わり、PerlやRubyのヒアドキュメントのように機能します。
変数補間(このformat方法を使用)の簡単な例は次のとおりです。
print ( '''親愛なる{recipient}様、あなたにはサニーデールを去って、二度と戻ってきてほしい。愛とは少し違う、{sender} ''' .format ( sender = "バフィー・ザ・ヴァンパイア・スレイヤー" , recipient = "スパイク" ))Finally, all of the previously mentioned string types come in "raw" varieties (denoted by placing a literal r before the opening quote), which do no backslash-interpolation and hence are very useful for regular expressions; compare "@-quoting" in C#. Raw strings were originally included specifically for regular expressions. Due to limitations of the tokenizer, raw strings may not have a trailing backslash.[20] Creating a raw string holding a Windows path ending with a backslash requires some variety of workaround (commonly, using forward slashes instead of backslashes, since Windows accepts both).
Examples include:
# A Windows path, even raw strings cannot end in a backslashwin_path:str=r"C:\Foo\Bar\Baz\"# Error:# File "<stdin>", line 1# win_path: str = r"C:\Foo\Bar\Baz\"# ^# SyntaxError: EOL while scanning string literaldos_path:str=r"C:\Foo\Bar\Baz\ "# avoids the error by addingprint(dos_path.rstrip())# and removing trailing space# prints('C:\\Foo\\Bar\\Baz\\')quoted_dos_path:str=r'"{}"'.format(dos_path)print(quoted_dos_path)# prints '"C:\\Foo\\Bar\\Baz\\ "'# A regular expression matching a quoted string with possible backslash quotingprint(re.match(r'"(([^"\\]|\\.)*)"',quoted_dos_path).group(1).rstrip())# prints 'C:\\Foo\\Bar\\Baz\\'code:str='foo(2, bar)'# Reverse the arguments in a two-arg function callprint(re.sub(r'\(([^,]*?),([^ ,]*?)\)',r'(\2, \1)',code))# prints 'foo(2, bar)'# Note that this won't work if either argument has parens or commas in it.String literals appearing contiguously and only separated by whitespace (including new lines using backslashes), are allowed and are aggregated into a single longer string.[21] Thus
title:str="One Good Turn: " \ 'A Natural History of the Screwdriver and the Screw'is equivalent to
title:str="One Good Turn: A Natural History of the Screwdriver and the Screw"Since Python 3.0, the default character set is UTF-8 both for source code and the interpreter. In UTF-8, unicode strings are handled like traditional byte strings. This example will work:
s:str="Γειά"# Hello in Greekprint(s)Numeric literals in Python are of the normal sort, e.g. 0, -1, 3.4, 3.5e-8.
Python has arbitrary-length integers and automatically increases their storage size as necessary. Prior to Python 3, there were two kinds of integral numbers: traditional fixed size integers and "long" integers of arbitrary size. The conversion to "long" integers was performed automatically when required, and thus the programmer usually did not have to be aware of the two integral types. In newer language versions the distinction is completely gone and all integers behave like arbitrary-length integers.
Python supports normal floating point numbers, which are created when a dot is used in a literal (e.g. 1.1), when an integer and a floating point number are used in an expression, or as a result of some mathematical operations ("true division" via the / operator, or exponentiation with a negative exponent).
Python also supports complex numbers natively. The imaginary component of a complex number is indicated with the J or j suffix, e.g. 3 + 4j.
Python has syntactic support for the creation of container types.
リスト(クラスlist)は任意の型の項目の可変シーケンスであり、特別な構文を使用して作成できます。
my_list : list [ int | str ] = [ 1 , 2 , 3 , "a dog" ]または通常のオブジェクト作成を使用する
my_second_list : list [ int ] = [] my_second_list . append ( 4 ) my_second_list . append ( 5 )タプル(クラスtuple)は、任意の型の項目からなる不変のシーケンスです。タプルを作成するための特別な構文もあります。
my_tuple : tuple [ int | str ] = 1 , 2 , 3 , "four" my_tuple : tuple [ int | str ] = ( 1 , 2 , 3 , "four" )タプルはカンマで区切られた項目によって作成されますが、可読性を高めるために通常は全体を括弧で囲みます。空のタプルは で表され()、単一の値を持つタプルは で作成できます(1,)。
セット(クラス)は、重複のない任意の型のハッシュ可能なアイテム[ 22 ]setの可変コンテナです。アイテムは順序付けられていませんが、セットはアイテムの反復処理をサポートしています。セットの作成構文は中括弧を使用します。
my_set : set [ Any ] = { 0 , (), False }Python のセットは数学の集合と非常によく似ており、集合の積集合や和集合などの演算をサポートしています。Python には、不変の集合を表すクラスもあります。詳しくはコレクション型をfrozenset参照してください。
辞書(クラスdict)は、キーと対応する値を関連付ける可変マッピングです。Python には辞書を作成するための特別な構文があります({key: value})。
my_dictionary : dict [ Any , Any ] = { "key 1" : "value 1" , 2 : 3 , 4 : []}辞書構文はセット構文と似ていますが、コロンの有無が異なります。空のリテラルは空のセット{}ではなく空の辞書を生成します。空のセットは、代わりに非リテラルコンストラクタを使用して作成されます。set()
Pythonには、通常の数学的優先順位+を持つ演算子、、、、(「真の除算」)、(切り捨て除算)、(剰余)、および(べき乗-)が含まれています。*///%**
Python 3 では、x / yは「真の除算」を実行します。つまり、 と の両方xがy割り切れる整数であっても、常に浮動小数点数を返します。
print ( 4/2 ) # 2.0と出力される整数除算または切り捨て除算//を実行し、商の切り捨て値を整数として返します。
Python 2(および他のほとんどのプログラミング言語)では、明示的に要求されない限り、x / y整数除算が実行され、入力のいずれかが浮動小数点数である場合にのみ浮動小数点数が返されました。しかし、Pythonは動的型付け言語であるため、どの演算が実行されているかを常に判別できるとは限らず、しばしば微妙なバグが発生しました。そのため、 Python 3では//演算子が導入され、演算子の意味論が変更されました/。
比較演算子、つまり==、、、、、、、!=および<[ 23 ]は、あらゆる>種類の値に使用されます。数値、文字列、シーケンス、およびマッピングはすべて比較できます。Python 3では、異なる型(たとえば、となど)には一貫した相対的な順序がなく、これらの型を比較しようとすると例外が発生します。Python 2では、異なる型を比較することは可能でしたが(たとえば、文字列が整数より大きいか小さいかなど)、順序は未定義でした。これは歴史的な設計上の癖と考えられ、最終的にPython 3で削除されました。<=>=isis notinnot instrintTypeError
のような連鎖比較式は、Ca < b < c言語や類似の言語に見られるような特殊な意味ではなく、数学における意味とほぼ同じ意味で使用されます。項は順番に評価および比較されます。この操作は短絡評価方式を採用しており、判定が明確になった時点で評価が必ず停止します。つまり、が偽の場合、式が真になることはあり得ないため、は決して評価されません。a < bc
副作用のない式の場合、a < b < cは と同等ですa < b and b < c。ただし、式に副作用がある場合は、大きな違いがあります。は正確に 1 回a < f(x) < b評価されますが、は の値がより小さい場合は 2 回、それ以外の場合は 1 回評価されます。f(x)a < f(x) and f(x) < baf(x)
""Python のすべてのバージョンにおいて、ブール演算子は、0、None、0.0、[]、などのゼロ値または空値を{}false として扱い、一般的に空でないゼロ以外の値を true として扱います。ブール値Trueおよび は、 Python 2.2.1 で定数 (およびFalseのサブクラス) として言語に追加され、Python 3 で完全なキーワードに変更されました。 や などの二項比較演算子は、またはを返します。10==>TrueFalse
ブール演算子andと は最小限の評価をor使用します。たとえば、はゼロ除算例外を発生させません。これらの演算子は、やではなく、最後に評価されたオペランドの値を返します。したがって、式 はに評価され、は に評価されます。y == 0 or x/y > 100TrueFalse(4 and 5)5(4 or 5)4
Python は、整数または プレフィックス付きで記述されたバイナリ数に対してビット演算を実行できます0b。 は、 を ビット左にx << yシフトし、右にゼロを追加します。も同様ですが、右にシフトし、最左端のビットのコピーを左に追加します。 演算子はビットごとの AND を実行し、はビットごとの OR を実行し、のビットごとの補数/NOT を返し、 はビットごとの XOR を実行します。これは、記号が通常べき乗演算子として使用されるのとは異なります。 [ 24 ] [ 25 ]xyx >> yxx & yx | y~ xxx ^ y^
Pythonの強みの一つは、関数型プログラミングスタイルが利用できることであり、これによりリストやその他のコレクションの操作がはるかに容易になる。
そのような構文の一つにリスト内包表記があり、これは次の形式で表現できます。
l :リスト[ Any ] = [フィルター式の場合、source_listの要素のマッピング式]リスト内包表記を使用して、2の最初の5つのべき乗を計算する:
powers_of_two : list [ int ] = [ 2 ** n for n in range ( 1 , 6 )]クイックソートアルゴリズムは、リスト内包表記を用いることで、簡潔に(ただし非効率的に)表現できる。
T : TypeVar = TypeVar ( "T" )def qsort ( l : list [ T ]) -> list [ T ]: if l == []: return [] pivot : T = l [ 0 ] return ( qsort ([ x for x in l [ 1 :] if x < pivot ]) + [ pivot ] + qsort ([ x for x in l [ 1 :] if x >= pivot ]))Python 2.7+ [ 26 ]は、セット内包表記[ 27 ]と辞書内包表記[ 28 ]もサポートしています。
Pythonでは、関数は第一級オブジェクトであり、動的に作成および受け渡しが可能です。
Pythonにおける匿名関数のサポートは限定的で、構文は ですlambda。例として、入力値を二乗する匿名関数 があり、引数として 5 を指定して呼び出されます。
f : Callable [[ int ], int ] = lambda x : x ** 2 f ( 5 )ラムダ式は文ではなく式のみを含むように制限されていますが、ショートサーキットを使用することでラムダ式内で制御フローを実装することは可能ですが、その方法は洗練されていません。[ 29 ]また、条件式を使用することでより慣用的な方法で実装できます。[ 30 ]
Pythonはバージョン2.2以降、字句クロージャをサポートしています。以下は、指定された関数の導関数を近似する関数を返す関数の例です。
def derivative ( f : Callable [[ float ], float ], dx : float ): """ 適切な小ささの区間 dx を使用してf の導関数を近似する関数を返します。 """ def function ( x : float ) -> float : return ( f ( x + dx ) - f ( x )) / dx return functionしかし、Python の構文は、他の言語のプログラマーにクロージャがサポートされていないと思わせることがあります。Pythonの変数スコープはglobal、スコープが明示的に宣言されていない限り、変数に値を代入するスコープによって暗黙的に決定されますnonlocal。[ 31 ]
クロージャによる名前と値のバインドは、関数内からは変更できないことに注意してください。例:
def foo ( a : int , b : int ) -> None : print ( f "a: { a } " ) print ( f "b: { b } " ) def bar ( c : int ) -> None : b = c print ( f "b*: { b } " ) bar ( a ) print ( f "b: { b } " )print ( foo ( 1 , 2 )) # 出力: # a: 1 # b: 2 # b*: 1 # b: 2そしてb、クロージャのスコープからわかるように、は以前の値を保持しています。b内部関数内のの変更されたバインディングは伝播されませんでした。これを回避するには、でnonlocal bステートメントを使用しますbar。Python 2 (にはがありませんnonlocal) では、通常の回避策は可変値を使用して、バインディングではなくその値を変更することです。たとえば、要素が 1 つのリストなどです。
Python 2.2でオプション機能として導入され、バージョン2.3で正式化されたジェネレーターは、そうでなければメモリを大量に消費したり、計算負荷の高いリストを返す関数を遅延評価するためのPythonの仕組みです。
これは、素数を遅延生成する例です。
itertoolsをインポートdef generate_primes ( stop_at : Optional [ int ] = None ) -> Iterator [ int ]: primes : list [ int ] = [] for n in itertools . count ( start = 2 ): if stop_at is not None and n > stop_at : return # StopIteration 例外が発生しますcomposite : bool = False for p in primes : if not n % p : composite = True break elif p ** 2 > n : break if not composite : primes . append ( n ) yield nこの関数を呼び出すと、返された値はリストのように反復処理できます。
for i in generate_primes ( 100 ): # 0から100までの素数を反復処理するprint ( i )for i in generate_primes (): # すべての素数を無限に反復処理するprint ( i )ジェネレータの定義は関数の定義とほぼ同じように見えますが、キーワードyieldの代わりにが使われていreturnます。しかし、ジェネレータは永続的な状態を持つオブジェクトであり、同じスコープに繰り返し出入りすることができます。ジェネレータ呼び出しは、リストや、要素を反復処理する他の構造体の代わりに使用できます。for例のループで次の項目が必要になるたびにジェネレータが呼び出され、次の項目が返されます。
ジェネレーターは、上記の素数の例のように無限である必要はありません。ジェネレーターが終了すると、内部例外が発生し、呼び出し元のコンテキストに値がもうないことが通知されます。forその後、ループやその他の反復処理が終了します。
Python 2.4で導入されたジェネレータ式は、リスト内包表記の遅延評価版です。上記のセクションで紹介した素数ジェネレーターを使えば、遅延評価されるものの、完全な無限ではないコレクションを定義できます。
itertoolsをインポートprimes_under_million : Iterator [ int ] = ( i for i in generate_primes () if i < 1000000 ) two_thousandth_prime : Iterator [ int ] = itertools . islice ( primes_under_million , 1999 , 2000 ) . next ()これだけの数の素数を生成するために必要なメモリと時間のほとんどは、実際に必要な要素にアクセスするまで使用されません。残念ながら、ジェネレーターに対して単純なインデックス付けやスライスを行うことはできず、itertoolsモジュールを使用するか、独自のループを作成する必要があります。対照的に、リスト内包表記は機能的には同等ですが、すべての処理を実行する際に貪欲になります。
primes_under_million : list [ int ] = [ i for i in generate_primes ( 2000000 ) if i < 1000000 ] two_thousandth_prime : int = primes_under_million [ 1999 ]リスト内包表記は、たとえほとんどの要素にアクセスしなくても、すぐに大きなリスト(この例では78498個の要素を持つリストだが、一時的に200万以下の素数のリストを作成する)を作成します。ジェネレータ内包表記の方が簡潔です。
リストとジェネレーターには内包表記/式がありましたが、Python 2.7より前のバージョンでは、他のPython組み込みコレクション型(辞書とセット)はリストまたはジェネレーターを使って無理やり実装する必要がありました。
squares = dict (( n , n * n ) for n in range ( 5 )) # Python 3.5 以降では squares の型は dict[int, int] ですprint ( squares ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}と出力されますPython 2.7と3.0では、リスト内包表記と同様に、辞書内包表記とセット内包表記を導入することで、すべてのコレクション型を統一しました。
print ([ n * n for n in range ( 5 )]) # 通常のリスト内包表記 # [0, 1, 4, 9, 16] と出力されますprint ({ n * n for n in range ( 5 )}) # セット内包表記 # {0, 1, 4, 9, 16} と出力されます print ({ n : n * n for n in range ( 5 )}) # 辞書内包表記 # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} と出力されますPython はほとんどのオブジェクト指向プログラミング (OOP) 技術をサポートしています。クラス階層内だけでなく、ダックタイピングによってもポリモーフィズムが可能です。任意のオブジェクトは任意の型に使用でき、適切なメソッドと属性があれば機能します。また、クラス、関数、数値、モジュールなど、Python のすべてがオブジェクトです。Python は、クラスの機能を拡張するための高度なツールであるメタクラスもサポートしています。当然ながら、多重継承を含む継承もサポートされています。Python は、名前マングリングを使用したプライベート変数のサポートが非常に限られています。情報隠蔽は、問題のクラスに美的感覚に欠ける、または計画性のない内部構造が含まれていることを示唆するとして、一部の人々から非 Python 的と見なされているため、実際にはほとんど使用されていません。「私たちは皆、責任あるユーザーです」というスローガンがこの姿勢を表すのに使われています。[ 32 ]
モジュールと同様に、Pythonのクラスも定義とユーザーの間に絶対的な障壁を設けるのではなく、ユーザーが「定義に踏み込まない」という礼儀を重んじることを期待している。
— 9. クラス、Python 2.6 チュートリアル(2013)
データメンバーを読み取るためのアクセサメソッドの使用など、OOPの原則はPythonでは強制されません。Pythonが関数型プログラミングの構成要素を提供しながらも参照透過性を要求しないのと同様に、オブジェクトシステムを提供しながらもOOPの振る舞いを要求しません。さらに、プロパティを使用してクラスを再定義することは常に可能です(プロパティを参照)。これにより、呼び出しコードで特定の変数が設定または取得されたときに、実際には関数呼び出しが呼び出されるため、spam.eggs = toast実際にはが呼び出される可能性があります。これはアクセサ関数の実用的な利点を無効にし、プロパティがオブジェクトのインターフェースの正当な部分となるため、実装の詳細を反映する必要がないため、 OOPのspam.set_eggs(toast)ままです。eggs
Python 2.2 では、「新スタイル」クラスが導入されました。新スタイルクラスでは、オブジェクトと型が統一され、型のサブクラス化が可能になりました。中置演算子のカスタム動作を備えた、まったく新しい型を定義することもできます。これにより、Python 内で構文的に多くの革新的なことが可能になります。また、Python 2.3 では、多重継承のための新しいメソッド解決順序が採用されました。さらに、属性へのアクセスや設定中にカスタムコードを実行することも可能になりましたが、これらの手法の詳細は Python のバージョン間で進化しています。
このwithステートメントはリソースを処理し、ユーザーがコンテキストマネージャプロトコルを使用できるようにします。[ 33 ]スコープに入るときに1 つの関数 ( __enter__()) が呼び出され、スコープを__exit__()抜けるときに別の関数 ( ) が呼び出されます。これにより、リソースの解放を忘れることがなくなり、使用中に例外が発生した場合にリソースを解放するなど、より複雑な状況にも対応できます。コンテキストマネージャは、ファイル、データベース接続、テストケースなどでよく使用されます。
プロパティを使用すると、属性アクセスと同じ構文を使用して、オブジェクトインスタンスに対して特別に定義されたメソッドを呼び出すことができます。プロパティを定義するクラスの例を以下に示します。
class MyClass : def __init__ ( self ) -> None : self . _a : int = 0@property def a ( self ) -> int : return self . _a@ a.setter # プロパティを書き込み可能にするdef a ( self , value : int ) - > None : self._a = value__get__(self, instance, owner)3 つの特殊メソッド、 、のいずれか 1 つ以上を定義するクラスは__set__(self, instance, value)、__delete__(self, instance)記述子として使用できます。記述子のインスタンスを 2 番目のクラスのクラス メンバーとして作成すると、そのインスタンスは 2 番目のクラスのプロパティになります。[ 34 ]
Pythonでは、`class`と`static`デコレータを使用して、クラスメソッドと静的メソッドを作成できます@classmethod。@staticmethodクラスメソッドの最初の引数は、インスタンスへの自己参照ではなく、クラスオブジェクトです。静的メソッドには特別な最初の引数はありません。インスタンスもクラスオブジェクトも静的メソッドには渡されません。
Pythonは、プログラムにおけるエラー状態やその他の「例外的な」イベントをテストする手段として、例外処理をサポートし、広く利用しています。
Pythonのスタイルでは、エラーが発生する可能性がある場合は例外処理を用いることが推奨されます。ファイルやリソースを実際に使用する前にアクセス権をテストするのではなく、Pythonではまず使用を試み、アクセスが拒否された場合に例外をキャッチするのが一般的です。
例外は、エラーが発生していない場合でも、より一般的な非ローカルな制御の移譲手段として使用できます。たとえば、 Pythonで書かれたMailmanメーリングリストソフトウェアは、メッセージを拒否するか、モデレーターの承認を待つという決定が下された場合に、深くネストされたメッセージ処理ロジックから抜け出すために例外を使用します。
if例外は、特にスレッド環境では、ブロックの代替としてよく使用されます。よく引用されるモットーは、EAFP、つまり「許可を求めるより許しを請う方が簡単だ」[ 35 ]で、これはグレース・ホッパーに帰せられています。[ 36 ] [ 37 ]代替案として、LBYL、つまり「軽率な行動は避ける」として知られるものがあり、これは前提条件を明示的にテストします。[ 38 ]
この最初のコード例では、LBLYLのアプローチに従い、アクセス前に属性の明示的なチェックが行われています。
if hasattr ( spam , "eggs" ) : ham = spam.eggs else : handle_missing_attr ( )この2番目のサンプルはEAFPパラダイムに従っています。
try : ham = spam.eggs except AttributeError : handle_missing_attr ( )これら 2 つのコード サンプルは、パフォーマンスに違いはあるものの、同じ効果があります。spamに 属性がある場合、EAFP サンプルの方が高速に実行されます。に 属性がないeggs場合(「例外」の場合)、EAFP サンプルの方が低速に実行されます。特定のケースでは、Pythonプロファイラを使用してパフォーマンス特性を判断できます。例外ケースがまれな場合は、EAFP バージョンの方が代替案よりも平均パフォーマンスが優れています。さらに、チェックから使用までの時間(TOCTTOU) の脆弱性、その他の競合状態[ 37 ] [ 39 ]を回避し、ダック タイピングと互換性があります。EAFP の欠点は、ステートメントでのみ使用できることです。例外は、ジェネレータ式、リスト内包表記、またはラムダ関数でキャッチできません。spameggs
Python コードに注釈を付ける方法は 2 つあります。1 つは、コードの一部が何をするかを示すためにコメントを使用する方法です。1 行のコメントはハッシュ文字 ( #) で始まり、行末まで続きます。複数行にわたるコメントは、代入やその他の方法で評価されないものの、他のステートメントの間に挿入される複数行の文字列 (各行の末尾に区切り文字として"""または'''を使用) によって実現されます。
コードにコメントを付ける:
import sysdef getline () - > str : return sys.stdin.readline ( ) # 1行を取得して返す複数行のコードにコメントを付ける方法:
def getline () -> str : """この関数は 1 行を取得して返します。 例として、複数行のドキュメント文字列を以下に示します。この文字列全体は、 getline.__ doc__ としてアクセスできます。 """ return sys.stdin.readline ( )ドキュメンテーション文字列 ( docstring ) は、モジュール、クラス、メソッド、または関数内の最初のインデントされた行として割り当てられずに単独で配置される文字列であり__doc__、その内容は という名前の属性として自動的に設定されます。この属性は、オブジェクトの目的、動作、および使用法を人間が読みやすい形で記述することを目的としています。組み込み関数は、属性helpに基づいて出力を生成します。このような文字列は、単一行文字列の場合は または__doc__で区切ることができ、複数行にわたる場合は、またはで区切ることができます。これは、複数行文字列を指定するための Python の表記法です。ただし、言語のスタイルガイドでは、単一行および複数行の docstring の両方に、トリプルダブルクォート ( ) を使用することが推奨されています。 [ 40 ]"'"""'''"""
1行のドキュメント文字列:
def getline () - > str : """標準入力から1行を取得して返します。" " " return sys.stdin.readline ( )複数行のドキュメント文字列:
def getline () - > str : """標準入力から1行を取得して返します 。 " "" return sys.stdin.readline ( )ドキュメンテーション文字列は、プログラマーが望むだけ長くすることができ、改行を含めることができます。コメントとは異なり、ドキュメンテーション文字列自体はPythonオブジェクトであり、Pythonが実行する解釈コードの一部です。つまり、実行中のプログラムは自身のドキュメンテーション文字列を取得してその情報を操作できますが、通常の用途は、ドキュメンテーション文字列で説明されているオブジェクトを呼び出す方法を他のプログラマーに伝えることです。
Pythonコードからドキュメント文字列を抽出してドキュメントを生成できるツールがあります。ドキュメント文字列はhelp()、インタプリタの関数、またはシェルのpydocコマンドからもアクセスできますpydoc。
doctest標準モジュールは、 Pythonシェルセッションからコピーされたインタラクションをドキュメント文字列に使用してテストを作成するのに対し、docoptモジュールはそれらを使用してコマンドラインオプションを定義します。
デコレータは、関数、メソッド、またはクラス定義を変更するために使用される呼び出し可能な Python オブジェクトです。デコレータには、定義される元のオブジェクトが渡され、変更されたオブジェクトが返されます。このオブジェクトは、定義内の名前にバインドされます。Python デコレータは、 Java アノテーションに一部影響を受けており、構文も似ています。デコレータ構文は、シンボルとしてを使用する、純粋なシンタックスシュガーです。ただし、コンパイラ用またはリフレクションでの読み取り用にメタデータを追加するために使用されるほとんどのプログラミング言語の一般的な属性とは異なり、 Python デコレータはメタデータを付加するために使用されるのではなく、実行可能なラッパーとして使用されます。@
@viking_chorus def menu_item () -> None : print ( "spam" )と同等
def menu_item () -> None : print ( "spam" ) menu_item = viking_chorus ( menu_item )デコレータはメタプログラミングの一種であり、デコレータが対象とする関数やメソッドの動作を強化します。例えば、以下のサンプルでは、呼び出されるたびに が8 回実行されるviking_chorus可能性があります(スパムスケッチを参照)。menu_item
R : TypeVar = TypeVar ( "R" )def viking_chorus ( myfunc : Callable [ ... , R ]) -> Callable [ ... , None ]: def inner_func ( * args : * tuple [ Any , ... ], ** kwargs : Unpact [ dict [ str , Any ]]) -> None : for i in range ( 8 ): myfunc ( * args , ** kwargs ) return inner_func関数デコレータの一般的な用途は、クラスメソッドや静的メソッドの作成、関数属性の追加、トレース、事前条件と事後条件の設定、同期などですが、[ 41 ]末尾再帰の排除、[ 42 ]メモ化、さらには他のデコレータの記述の改善など、はるかに多くの用途に使用できます。 [ 43 ]
装飾要素は、隣接する行に複数配置することで連結できます。
@invincible @favourite_colour ( "Blue" ) def black_knight () -> None : passと同等
def black_knight () -> None : pass black_knight = invincible ( favourite_colour ( "Blue" )( black_knight ))または、中間変数を使用する
def black_knight () -> None : pass blue_decorator = favourite_colour ( "Blue" ) decorated_by_blue = blue_decorator ( black_knight ) black_knight = invincible ( decorated_by_blue )上記の例では、favourite_colourデコレータファクトリは引数を取ります。デコレータファクトリはデコレータを返す必要があり、そのデコレータは、装飾対象のオブジェクトを引数として呼び出されます。
def favourite_colour ( colour : str ) -> Callable [[ Callable [[], R ]], Callable [[], R ]]: def decorator ( func : Callable [[], R ]) -> Callable [[], R ]: def wrapper () -> R : print ( colour ) func () return wrapper return decoratorこれにより、関数が実行される前にblack_knight色()が出力されるように関数が装飾されます。クロージャは、色引数が返されてスコープ外になった場合でも、最も内側のラッパー関数からアクセス可能であることを保証し、これがデコレータが機能する理由です。"Blue"black_knight
名前とは裏腹に、Pythonのデコレータはデコレータパターンの実装ではありません。デコレータパターンは、静的型付けのオブジェクト指向プログラミング言語で使用されるデザインパターンで、実行時にオブジェクトに機能を追加できるようにするものです。一方、Pythonのデコレータは、関数やメソッドに定義時に機能を追加するため、デコレータパターンのクラスよりも高レベルの構造と言えます。Pythonはダックタイピングを採用しているため、デコレータパターン自体は簡単に実装できますが、通常はデコレータパターンとはみなされません。
CやJavaなどの波括弧言語のユーザーは、Python がブロック区切り規則に従うことを期待または希望することがあります。波括弧で区切られたブロック構文は繰り返し要求されてきましたが、コア開発者によって一貫して拒否されてきました。Python インタープリタには、この問題に関する開発者の考えをまとめたイースターエッグが含まれています。このコードは例外を発生させます。このモジュールは通常、将来のバージョンの Python の機能を提供するために使用されます。from __future__ import bracesSyntaxError: not a chance__future__
もう1つの隠されたメッセージである「Pythonの禅」 ( Pythonの設計哲学の要約)は、 を試みると表示されますimport this。
Hello world!import文が使用されると、このメッセージが表示されますimport __hello__。Python 2.7では、代わりに がHello world!出力されますHello world...。
このantigravityモジュールをインポートすると、Web ブラウザがxkcdコミック353に開きます。このコミックは、このようなモジュールのユーモラスな架空の使用例を描いており、Python モジュールが追加機能を簡単に実現できることを実証することを目的としています。[ 44 ] Python 3 では、このモジュールにはxkcdコミック426を参照した「geohash」アルゴリズムの実装も含まれています。[ 45 ]
nonlocalキーワードはPEP 3104で採用されました。2014年12月2日にWayback Machineにアーカイブされました。{{cite web}}: CS1メンテナンス: アーカイブサービスは非推奨になりました (リンク)