作者: 機械伯爵
日時: 2009/11/4(21:53)
※この前に序文と、目次、さらに以下に挙げる概要よりさらに大雑把な
内容紹介が入ります。

1.概略

1-0.文法分析と構成要素

 文法の話をするには、まずその構成要素を明確に示す必要があります。
 前述の通りリファレンスの要素は、精確/厳密ではありますが、人間が理解す
るにはやや不便です。
 そこで一般の人が理解/利用しやすい文法を再構築するため、用語/分類など
を敢えて再定義します。
 勿論、正式な用語は支障のない限り取り入れ、再定義の幅は出来る限り抑えます。



1-1.構成要素(component)

 まず、構成要素を、以下のように分類します。

・構文キーワード(syntax keyword)
・オブジェクト(object)
・演算子(operator)
・代入子(assignor)
・空白(white space)
・特殊記号(special symbol)

 よく、『Pythonは全てオブジェクトで出来ている』といわれますが、これは被
演算子(operant=演算子によって演算される対象)に限ります。
 Schemeのように演算子が全て関数で、それが全てオブジェクトとして扱える、
というほど徹底していません(例えば'+'記号のリストは出来ません)。
 また、Smalltalkのように「オブジェクト←メッセージ」で全てを記述してい
るわけではなく、制御構造などの記述には、ごく古典的な構文キーワードを用い
た文法を採用しています。
 この点、Pythonの基本構文は、C++やJavaのような文法に近いといえるでしょ
う(尤も、関数はオブジェクト扱いになりますが)
 Pythonでは、文(statement)と式(expression)がはっきりと区別されています。
 式は単独で文(式文 expression statement)になりますが、文の全てが式とい
うわけではありません。
 構文キーワードを用いた制御構造や代入文などは、一部を除き、式扱いできな
い文(非式文 not-expression statement)となっています。
 文の区切りは、文末がバックスラッシュ('\')で終わらない改行で行われます
(バックスラッシュで終わる行の改行は空白扱いとなります)
 ただし、各種『括弧(parenthesis)』が使用されていた場合、『暗黙の行の接
続(implicit line joining)』によってカッコが終了するまでは一行は終了しな
いものとします。
 ちなみに括弧は、リファレンスでは『デリミタ(delimiter)』扱いですが、本
書では『演算子(operator)』に含めて説明します。
 '='などの代入に関する記号も、リファレンスではデリミタ扱いですが、本書
では独自に『代入子(assignor)』という用語を用いて、識別子の代入
(assignment)に用いるものをまとめました。
 他言語では代入に関わる記号も代入演算子として演算子の一種として扱うもの
もありますが、Pythonでは演算子と代入子をしっかりと区別します。
 なぜなら、演算子を用いた結果は式となりますが、代入子を用いた代入文
(assignment statement)は式扱いにはならないからです。
 空白(スペースとタブ)は、キーワード(構文キーワードと演算子キーワード)
と識別子(identifier)を区切るためと、制御ブロックのインデントのために用い
られます。
 読みやすさのために、要素と要素の間には適宜空白を使用することが許されて
いますが、Pythonのインデントルールのため、行頭のスペースについては、厳格
です。

※例えば、ブロックの中でもないのに、先頭に空白を置くだけでエラーになりま
す。

 特殊記号(special symbols)には、上記のいずれにも当てはまらない記号につ
いて集めました。
 この分類の記号については、複数の役割を持っている場合が多いので注意が必
要です。
 例えば、コロン(':')は制御ブロックのヘッダ部分のデリミタ(delimiter)とし
て使用される他、辞書リテラルでキーとアイテムを分ける部分で使用されたり、
リストの演算子の一種であるスライスで使用したり、引数の型勧告に使用したり
します。
 他の特殊記号としては、複数行纏め書きのためのセミコロン(';')、引数リ
ストなどに用いるアスタリスク('*')、デコレータの開始記号であるアットマー
ク('@')などがあります。(アスタリスクは、乗算の演算子としても使用されま
す)



1-2.キーワード(keyword)/予約語(reserved word)

 キーワードや予約語と呼ばれる、識別子に使えない特殊な文字の組み合わせに
は、機能的に3種類のものが含まれています。
 以下の分類は、この文書独自のものです。

オブジェクトキーワード(object keyword):
	False,None,True演算子キーワード(operator keyword):
	and, in, is, not, or
構文キーワード(syntax keyword):
	as, assert, break, class, continue, def, del, elif, else, except, 
	finally, for, from, global, if, import, lambda, nonlocal, pass, 
	raise, return, try, while, with, yield

 オブジェクトキーワードは、識別子として再定義できないキーワードであるだ
けで、扱いは通常のオブジェクトに準じます。
 演算子キーワードは、記号の代わりに特定の文字列を用いたもので、扱いは演
算子に準じます。
 ちなみにメンバーテスト演算子inは、forと一緒に使うことによって、違う意
味を持ちます。
 構文キーワードには、基本構文の範疇に無い拡張構文を導入する際に使用しま
す。
 殆どの拡張構文は非式文となりますが、一部は式文を形成します(lambda,や
if-elseなど)
 また、一部キーワードは、ループや関数定義の中など、特別な状況下でしか使
用できないものもあります(breakやreturnなど)



1-3.オブジェクト(object)

 オブジェクトという言葉には様々な定義があり、プログラミング言語の用法に
よって扱いが異なる厄介な言葉ですが、Pythonでは被演算子(operant)となりう
るもの全てを指します(式は被演算子ではありませんが、式が評価された値や式
オブジェクトは被演算子です)
 初期のPythonでは、オブジェクトに相当しない原始的な型のデータ(primitive 
type data)が存在しましたが、現在では、原始型扱いされていた数や文字列も全
てオブジェクトとなりました。
 モノとしてではなく性質としてのオブジェクト(Python object)とは、クラス
インスタンスであることを指します。
 つまりPythonでは、全てのオブジェクトがクラスインスタンス(class 
instance)です。

※クラスインスタンスとは、クラスという雛形から作られたオブジェクトという
意味

 Pythonではメタクラスプロトコル(metaclass protocol)を採用しているので、
クラス自身も、メタクラスのインスタンスです。

※メタクラスはクラスのクラス

 さらにPythonでは、関数(function)やメソッド(method)も全てオブジェクトと
して扱います。

※ただし関数やメソッドの扱いは、やや特殊です。

 括弧演算子を用いた関数適用を行わなければ、関数そのもののオブジェクトと
して扱います。
 オブジェクトの共通の性質は、以下のようなものがあります。

・識別子(identifier)の名前に束縛(bind)できる。すなわち代入可能・同じく属
性として代入可能・タプルなどのコンテナ(コレクション)に収納可能・必ず値
を持つので、真偽判定可能・関数の引数としての引渡しが可能

※プロパティー(property)は本来オブジェクトですが、例外的に標準的なオブジ
ェクトの扱いを受けないことがあります。

 メソッドやフィールドなどの属性(attribute)を持つオブジェクトは、識別子
や演算子によって、メソッドやフィールドにアクセスできます。
 Pythonには、属性の外部からのアクセスを、根本的に制限する仕組みはありま
せん(例外はプロパティーです)。
 オブジェクトには、可変オブジェクト(mutalbe object)と不変オブジェクト
(immutable object)の二種類があります。
 可変オブジェクトは、オブジェクト生成後にそのオブジェクトの内容が変更可
能(再代入ではなく、そのオブジェクト自身の属性が変更可能)ですが、不変オ
ブジェクトでは属性にアクセスすることはできても、変更することはできません。
 なお、可変オブジェクトであっても、組み込み型(builtin type)のオブジェク
トであった場合は、属性の追加などはできません。
 これらの組み込み型を拡張するには、組み込み型を継承した新しいクラスを定
義する必要があります(関数クラスなど、一部継承不可能なクラスもあります)。
 その他、Pythonではモジュール(module)もオブジェクト扱いされます。



1-4.演算子(operator)

 演算子は、Pythonに於いて関数呼び出し以外で演算を行うために選ばれた記号
群及び特定の文字列(キーワード演算子)です。
 Pythonの演算子は、日常にありふれた数学表現に極力対応しているため、その
適用順序も簡単な左結合ではありません。
 例えば加算記号の'+'は、括弧を使わない限り、乗算記号の'*'より必ず『優先
順位(precedence)』が低くなります。
 Pythonでは、ユーザーが定義したオブジェクトに関しては、演算子がどのよう
に働くかを定義することができますが、演算子の優先順位や結合順位を変更する
ことはできません。
 また、演算子として使う記号は、決まったもの以外、使用できません。
 さらに、単項演算子/二項演算子といった使い方についても、言語として規定
された通りにしか使えません。
 例えば'+'は単項演算子としても二項演算子としても使えますが、'/'は二項演
算子としてしか使えませんので、必ず両辺に被演算子を必要とします。
 Pythonで使用できる演算子と優先順位は以下の通りです(優先順位の低い順)

順位	演算子		説明低	lambda		λ式(Lambda expression)
↑	,		カンマ演算子(comma)
	or		論理和(Boolean OR)
	and		論理積(Boolean AND)
	not X		論理否定(Boolean NOT)
	in, not in	メンバーテスト(Membership tests)
	is, is not	同一性テスト(Identity tests)
	<, <=, >, >=, !=, ==
			比較(Comparisons)
	|		ビット演算の論理和(Bitwise OR)
	^		ビット演算の排他的論理和(Bitwise XOR)
	&		ビット演算の論理積(Bitwise AND)
	<<, >>		ビットシフト(Shifts)
	+, -		加減算(Addition and subtraction)
	*, /, //, %	乗除算、剰余算(Multiplication, division, 
			remainder)
	+x, -x		正負符号(Positive, negative)
	~x		ビット反転(Bitwise not)
	**		累乗算(Exponentiation)
	x[index]	添え字(Subscription)
	x[index:index]	スライス(Slicing)
	x(arguments...)	呼び出し(Call)
	x.attribute	属性参照(Attribute reference)
	(expressions...)
			束縛、タプル表示、ジェネレータ式
			(Binding, tuple display, generator expressions) 
	[expressions...]
			リスト表示(List display)
	{expressions...}
			辞書表示、集合表示(Dictionary or set display)

 二項演算子の同順位のものは、原則左から適用されますが、累乗を示す'**'に
ついては、右から適用されます。
 lambdaキーワードによるlambda文と、条件付評価式(if-else式)は、キーワー
ドを用いた結果が式になるので、優先順位の表に含めましたが、これらは本書で
はリテラル及び特殊構文の項で説明します。



1-5.括弧(parenthesis)、引用符(quotation mark)

 括弧は、リファレンスでは全てデリミタ(delimiter)に含まれていますが、前
述の通り本書では『グループ化/演算順位変更のための演算子』として扱います。
 括弧には種類があり、英語でも混乱しているので、本書での言葉でどの記号を
指すのかの対応表を以下に記しておきます。

種類		英語表記	漢字/仮名表記

括弧の総称	parenthesis	括弧
(...)		paren		丸括弧、パーレン
[...]		bracket		角括弧、ブラケット
{...}		brace		中括弧、ブレース

 細かく言えば、日本語の括弧は『括(くく)る弧』なので、当然丸いモノを指し
ます。
 また、英語でもbracketやbraceがドレを指すのか混乱している。

例)	square bracket	=> []
	bracket		=> 括弧一般 [],(),<>,{}

 よって上記の区分は本書のみでの呼称だと思って下さい。
 当然ですが括弧の順位は全て同じであり、より内側が優先されます。
 引用符は、Pythonでは文字列(string)のリテラル(literal)として利用します。
 単引用符も二重引用符も同義ですが、互いの引用符を中に記述することが出来
ます(つまり単引用符の中では二重引用符が、二重引用符の中では単引用符が、
単なる文字として使用できます)
 三重引用符は、単引用符の三回連続と、二重引用符の三回連続で表示されます
が、呼称は区別しません。

種類		英語表記	漢字/仮名表記
'...'		(single)quote	単引用符、クォート
"..."		double quote	二重引用符、ダブルクォート
'''...'''	triple quote	三重引用符、トリプルクォート
"""...'''	triple quote	三重引用符、トリプルクォート



1-6.代入子(assignor)

 リファレンスでは、代入文(assignment statements)および増加代入文
(augmented assignment statements)といった名称しか見えず、記号自体には名
称が無いので、代入文を生成する'='などの記号を、ここでは代入子と名づけま
す。
 代入子に分類される記号は以下の通りです。

	x = y
		単純代入
	x += y
		加算代入 ⇒ x = x + y
	x -= y
		減算代入 ⇒ x = x - y
	x *= y
		乗算代入 ⇒ x = x * y
	x /= y
		真性除算代入 ⇒ x = x / y
	x //= y
		フロー除算代入 ⇒ x = x // y
	x %= y
		剰余算代入 ⇒ x = x % y
	x **= y
		累乗代入 ⇒ x = x ** y
	x &= y
		ビット論理積代入 ⇒ x = x & y
	x |= y
		ビット論理和代入 ⇒ x = x | y
	x ^= y
		ビット排他的論理積和代入 ⇒ x = x ^ y
	x >>= y
		ビット右シフト代入 ⇒ x = x >> y
	x <<= y
		ビット左シフト代入 ⇒ x = y << y

 代入子と演算子では、適用した結果に生成されるものが異なります。
 演算子では、その結果が『式』となりますが、代入子では非式文の『代入文』
となります。
 よって、式の中に代入子を使った代入文を含めることは、基本的にはできませ
ん。
 代入文の非式文扱いについては、比較演算子の'=='と代入子の'='を書き間違
えないように、とよく説明されます。



1-7.特殊記号(special symbol)

 演算子にも代入子にもリテラル表記あてはまらない、拡張構文で用いられる記
号と用法を、以下に簡単に列挙します。

	*	アスタリスク(asterisk)
		仮引数リスト、引数リスト展開、余剰(rest)要素収納

	**	ダブルアスタリスク(double asterisk)
		キーワード引数、引数辞書展開

	@	アットマーク(at-mark, at-sign)
		修飾子(デコレータ decorator)適用

	:	コロン(colon)
		ブロックヘッダーデリミタ(block header delimiter)
		辞書のキーとアイテムのセパレータ
		スライス(slice)

	;	セミコロン(semicolon)
		複文接続

	#	シャープ(sharp)
		コメント

	\	バックスラッシュ(back slash)
		複数行継続

 詳細については、それぞれの項目を参照してください。