Python、はじめました

非IT系私文卒リーマン vs Python の全記録

【初めてのPython(第4章)】

f:id:pokita:20180426195830j:plain

ビルトインオブジェクト(筋トレ器具っぽい)の話。

ビルトインオブジェクトとはPythonがデフォルトで、提供してくれているオブジェクトのこと。プログラムにより自分で作る自作オブジェクトの対義語。

 

自作オブジェクトが何かというと、オブジェクト指向プログラミングで定義されるclass object():以下のこと。初めは「オブジェクト指向ってだからなに!?!」となって混乱することも多いのでざっとでいいので、こちらの先にこちらの記事を読んで見てください。

python3.hatenadiary.jp

C++とかだったら、Pythonビルトインオブジェクトのディクショナリ{}やタプル()は独自オブジェクトで作らなきゃないらしいから、やっぱPython優秀。

リテラル

辞書で調べると

リテラルとは変数の対義語であり、変更されない定数である。

とのこと。しかし、Pythonリテラルは変更できるので、決してこの”定数”って定義には一致しないかも。(リストにおけるappend()メソッドとか)

71pの表4-1にはその一覧が載っているけど、こちらのページがより参考になりました。

d.hatena.ne.jp

それぞれの型のリテラルには固有の作成方法があり、その表記方法で書かれたリテラルがその型になる。文字列なら""で囲む、ファイルオブジェクトならopen関数を使う等。

ダイナミックな型付け

Pythonインタプリタは、自動的にリテラルからその型を検知することができる。だから型宣言VBAで言うところのDim x As Long)がないらしい。これをダイナミックな型付けと言う。また、Pythonにおいて変数は、生成された既存のリテラルへのリファレンス(参照)を表すだけなので、変数自身は特定の型を持たない。そのため、例えば

X = "spam"
X = 3,14
という記述も可能である。一行目で"spam”という文字リテラルが生成され、変数xにそのリファレンスが渡された。二行目で3,14という浮動小数点数リテラルが生成され、変数xにそのリファレンスが渡された(上書きされた)。

変数xは渡されたリファレンスを返すだけであり、それ自身がリテラルを格納しているわけではない。変数の型宣言をする必要がない!のである。けっこう楽勝な言語ではな
いかこれ!!!!

型特有の操作

すべてのプログラムも書き出しは

X = "spam"
X = 3,14
という風に、直接記述しリテラルを生成するところから始まる。それを操作し、加工することがプログラムの本質である。その”操作”、についてなんだけど、どういう操作ができるかはオブジェクトの型によって決まる!

例えば、文字列"spam"やリスト["a","b","c"]は、一定の位置情報を持つシーケンスというオブジェクトに分類される。シーケンスをもつオブジェクトは以下のようなインデックス[]操作が可能である。
"spam"[0]
>>>"s"
L=["a","b","c"]
L[2]
>>>b
 しかし、以下のような操作だとエラーが出てしまう。
x = "123"
x[1]
>>>2
x = 123
x[1]
>>>TypeError:"int" object is not subscriptable
print(len(x))
>>>TypeError: object of 'int' type has no len()

これはx(123)が整数型であり、シーケンスを持たず、インデックス操作に対応していないためである。こうした感じで、オブジェクトはそれぞれのオブジェクトに対応したメソッド関数でしか操作できない。

なぜなら、ビルドイン関数(メソッド)は、その設計段階において(C言語で書かれている)対応するオブジェクト上に属性として書かれているためである。

メソッドと関数の違い、ビルトインメソッドの存在意義については以下の記事で。

python3.hatenadiary.jp
また演算子においても

x = 1
y = 2
x + y #数値オブジェクトにおける「+」
>>>3
X = "1"
Y = "2"
X + Y #文字オブジェクトにおける「+」
>>>"12"
というような感じで、オブジェクトによって処理が異なる。これは、演算子においてもそれが動くオブジェクトごとに、その働きが定義されているからに他ならない。これをポリモーフィズムと呼ばれる。

次は、ざっとビルドインオブジェクトの解説。

不変性

1.変数にシークエンスを持つリテラルを代入する
2.その変数のシークエンスに代入する処理を行う
3.その変数を呼び出すと参照されるリテラルは?
元のリテラル?それとも代入後のリテラル
実際にやってみる。
#文字列の場合
x = "spam"
x[1] = w #シーケンスへの代入
x
>>>"spam" #元のリテラルを返す
#リストの場合
x = ["s","p","a","m"]
x[1]="w"
x
>>>["s","w","a","m"] #代入後のリテラルを返す
この違いは、文字列が不変性を持つのに対し、リストは可変性を持つオブジェクトだからである。Pythonにおいて変数とは、あくまでも生成されたリテラルへの参照を表す存在である。シーケンスへの代入処理が行われると、文字列においては、参照付きじゃない代入後のリテラルが生成されるだけでありリストにおいては、参照付きのリテラルが更新されるのである。

数値

数字をベタ打ちすると生成されるビルドインオブジェクト。
x = 123
こんな感じですぐ作成できる。
+、ー、*、**、/、//
等の演算子を用いて計算することができるju
入力する文字を""で囲むことで生成されるビルドインオブジェクト。
x = ”123”
シーケンスを持つオブジェクトなので、各種のシーケンス操作に対応している。
x = ”123”
x[1]
>>>"2"
x + x
>>>"123123"
len(x) #シーケンスの長さを戻す関数
>>>3

リスト

記号”[]”の中にオブジェクトを”,”で区切って一定の順列で並べたもの。文字列とは異なり、リストのメソッドを使用することで特定の要素を上書きすることができる。
L = [1,2,3,4,5]
L[1]
>>>2
L.pop(1)
#指定されたシーケンスを返す。そのシーケンスをリストから削除する。
>>>2
L
>>>[1,3,4,5]

ディクショナリ

記号”{}”の中にオブジェクトを”:”と”,”で区切って入れたもの。入れるオブジェクトは”:”の前後でキーに分けられる。リストとは異なり、値はキーのみに紐付けられており順列情報を持っておらず、シーケンスはない。
D = {"a":"spam","b":"ham","c":"beer"}
print(D)
>>>{"a":"spam","c":"beer","b":"ham"}
print(D)
>>>{"b":"ham","c":"beer","a":"spam"}
順列情報を持ってるわけではないので、順番はランダム出でる。
(PyCharmで実行したところ順列通りに出てました…なぜ?)

等々のビルドインオブジェクトの解説が続く。ファイル型、bool型、set型、type型……。一体いくつあるんだ。悪名高いオブジェクト指向の説明も4.8.2で行ってる。はじめ読んだときはここ混乱しました。

それぞれの型の詳しい説明は後の章で行うので、今回はここまで。