トップ 一覧 検索 ヘルプ RSS ログイン

技術的雑談-Perl使いの為のPython2.5入門の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!技術的雑談-Perl使いの為のPython2.5入門

!!環境
*Python : 2.5
*OS : Python2.5が動けばどれでも

!!目的
*Perlが一応わかる人の為のPythonの説明
*ぶっちゃけ、perlもpythonも使えるようになればいいなぁ~と

!!アラカルト

!ソースコードの文字コードを指定する方法

ソースコードの最初の方に

 # -*- coding: エンコード形式 -*-

で指定することができる。

 # -*- coding: utf_8 -*-    … UTF-8
 # -*- coding: ms932 -*-    … WindowsでのShift-JIS
 # -*- coding: euc_jp -*-   … EUC-JP
 # -*- coding: iso2022_jp -*-   … (多分)JIS

!インデントでスコープを区切る

pythonの一番大きな特徴だと思います。
Perlでは{}を使ってブロックを定義するが、Pythonではインデントのレベルによってブロックを区切る。
インデントには空白かタブを使用可能。
つまり、'''同じ高さに書いてあるものは同じスコープ内'''ということです。

!try-catch-finally

try/catchの書き方。

 try:
 	~Tryの中身~
 exception 例外型[ ,例外インスタンス名]:
 	~例外処理~
 [exception 例外型2[ ,例外インスタンス名2]:
 	~別の型の例外処理~
 else:
 	~例外が起こらなかった時の処理~
 finally:
 	~例外の有無に関わらず実行される処理~

各項目ごとに「:」を最後につけるのを忘れずに。
「else:」がperlには無いものかな?

!例外のThrowの仕方

例外は以下の構文でthrowできます。

 raise 例外型[(例外型コンストラクタへの引数)]

catchブロック(exception内)では単に「raise」だけでcatchした例外を再Throwできる。


!コンストラクタ

コンストラクタは
 def __init__
で定義する。
引数の1番目は必ず自身のインスタンスとなるようなので、習慣的に「self」とする。
(オブジェクト指向Perlと同じ?)

!Classの定義

 class クラス名[(継承元のクラス名)]
で宣言する。


!Undefにあたるもの

キーワード「None」がそれに該当する。


!関数・メソッドの定義

def メソッド名[(仮引数[, 仮引数2…])]:
で定義する。
'''最後のコロンを忘れないこと!'''
メソッドの定義で戻り値型を限定することはできない。(perlもか。)

仮引数は「hoge=デフォルト値」で省略時のデフォルト値を指定することも可能らしい。
但し、引数のデフォルト値が設定されるのは
'''「関数の外のスコープで」''' '''「1回だけ」'''なので、リストなどをデフォルトを期待する場合には注意が必要。

例:デフォルト引数は1回しか適用されない
 def f(a, L=[]):
     L.append(a)
     return L
 
 print f(1)	# [1]
 print f(2)	# [1,2]
 print f(3)	# [1,2,3]

例:デフォルト引数の評価されるスコープとタイミング
 i = 5
 def f(arg=i):
 	print arg
 i = 6
 f()		# 5が表示される
 

!JavaのObject#toString()にあたるメソッド

class内では
 def __str__(self)
でstr()を通した時の文字列出力を実装できる。


!メソッド・関数からの戻り値の返し方

普通に「return 戻り値」を使用する。
戻り値型はObjectもOK。


!コメントの書き方

「#」以降は行末までコメントとして扱われる。
「"""」から次の「"""」は複数行コメントとして扱われる。


!モジュールの宣言

「モジュール名=ソースコードの末尾から「.py」をとった文字列」となる。
そこに至るまでのディレクトリをパッケージとして扱えるが、パッケージと認識される為には
そのディレクトリ内に
 __init__.py
というファイルがあることが条件。
'''____init____.py'''の中身は空でもかまわないが、パッケージ定数(変数)や「import hogehoge.*」を行った時に
読み込まれるべきモジュールリストを返す'''____all____'''変数を定義することができる。


!他のモジュールの使用宣言

「import」文を使用する。
「import 読み込むモジュールのFullName」で読み込んだ場合は読込先で使用する場合にフルネームでの指定が必要。

例:
 import aaa.bbb.Hoge
 
 a = aaa.bbb.Hoge

「from パッケージ名 import モジュール名」で読み込んだ場合はパッケージ名を省略した形で使用できる。

例:
 from aaa.bbb import Hoge
 
 a = Hoge

「from モジュールFullName import メソッド名(又は「*」)はモジュール名を省略した形でモジュール内のメソッドにアクセスできる。

例:
 from aaa.bbb.Hoge import *
 
 a = fuga(x)   # Hoge.fuga(x)メソッドをモジュール名無しでアクセスできる


!定義済み完了処理

あるオブジェクトが確実に後処理されるようにするには、try:~finally:を使う他に「with」を使用することもできる。

例:
 with open("afile.txt") as f:
 	for line in f:
 		print line
 # forが終わった時点でファイルfはcloseされる

VB.NETとかのWithと同じ。

!起動引数の取得

「sys.argv」配列でアクセス可能。


!perlの「use strict」にあたる設定<<ガセネタ>>

==ローカル変数の宣言を強制するなどの効果があるperlの「use stric」と同じ事をするには==
==「import strict」を行う。==

==ローカル変数を宣言するには「new 変数名[=初期値]」を使用する。==

==例:==
 import stric
 
 a = 10		# エラーになる
 new a = 10	# OK
 new b		# 初期値無しで宣言


'''2008/10/31 追記'''
実際にやってみると「strictなんてものは見つからない」と怒られます。
ガセネタだったようです。
!文字列の連結

普通に「+」で連結可能。

リテラル(文字定数)同士の連結は単に間に空白を1つ挟むだけでよい。
ただしリテラルと文字変数の結合はダメ。

例:
 a = "abc" + "def"	# 結果: "abcdef"
 b = "abc" "def"		# 結果: "abcdef"
 c = "abc" hoge		# エラー


!リテラル文字列の宣言

文字定数を宣言するには「"」か「'」で文字列を囲む。エスケープシーケンスは共に使用可能。
但し、Perlのように「"」と「'」でエスケープシーケンスの有無に差がない。

「r"abcdef\n"」のように先頭に「r」をつけると中のエスケープシーケンスが評価されない。

「u'あああああ'」のように先頭に「u」をつけるとUnicodeリテラルを生成する。

「ur'あああああ\n'」のように先頭を「ur」とするとUnicodeリテラルをエスケープシーケンスを評価しないで定義する。


!文字列へのインデクサ

文字列変数に対してインデクサを指定してn文字目を参照することができる。
インデックスは0から始まる。

例:
 a = "abcd"
 print a[0]	# 'a'
 print a[3]	# 'd'

さらにスライスを使ってJavaで言う「String#subString()」のようなこともできる。

例:
 a = "abcdefghij"
 print a[1:]	# 'bcdefghij'
 print a[1:3]	# 'bc'		1文字目から2文字目まで。(3文字目は含まれないことに注意!)
 print a[:3]	# 'abc'		0文字目から3個
 print a[:0]	# ''		空文字列
 print a[-2]	# 'i'		最後から2文字目
 print a[-5:-2]	# 'fgh'		最後から5文字目から2文字目まで
 print a[:-2]	# 'abcdefgh'	最後の2文字以外全て

ただし、インデクサやスライスで切り出した文字列を変更することはできない。

例:
 a = "abcdefghij"
 a[2] = "q"		# エラーになる

スライスの働きを覚えるには、
'''「最初の文字の左側が0」'''
'''「以降は文字と文字の間ごとに+1」'''
と考えると良い。(隙間を数えていると考える。)


!Unicodeからのエンコードの変換

perl5.8からは内部で(ほぼ)透過的にUnicode文字列が使えるが、Pythonは今のところ違うっぽい。

 u'あああ'.encode('utf-8')	# UnicodeをUTF-8に変換


!他エンコードからUnicodeへの変換

 unicode(他エンコードの文字列, 元のエンコード名)


!リスト

 a = [100, 'abcdef', object]
のようにしてリストを定義できる。
 a = []
で空のリストを定義できる。
リストの中は単一の型でなくても良い。

多次元配列を定義するには、
 b = [[1,2,3,4], [5,6,7,8]]
のように、リストのリストを作る。
リストのアイテムにリストを含めることができる。

リストには0から始まるインデックスでアクセスできる。
 print b[0][2]		# 3

リストにもスライスが使える。
扱いは文字列の時と同じ。


!リストへの追加

リストの最後に追加するには、
「a = a + [6]」のようにリスト同士を「+」で連結すればよい。


!リスト項目の削除

スライスを利用し、削除したいスライスに空配列を代入すればよい。

例:
 a = [1,2,3,4,5]
 a[1:2] = []
 print a			# [1,3,4,5]
 a = [1,2,3,4,5]
 a[0:3] = []
 print a			# [4,5]


!リストの長さを知る

len()関数を使う。
perlと違い、要素の「個数」が返る。
(最大添え字ではない)

例:
 a = [1,2,3,4,5]
 print len(a)		# 5


!文字列の長さを知る

同じく「len()」を使う。
Unicode文字列の場合、「文字数」が返る。
普通の文字列の場合、「占有するバイト数」が返る。

例:
 a = u'あいうえお'
 print len(a)		# 5
 a = a.encode('sjis')
 print len(a)		# 10


!for文

Pythonのfor文はperlで言うところの「for each」と同じ。

例:
 for x in [1,2,3,4,5,6]:		# 最後の「:」を忘れないように!
 	print x
 # 1,2,3,4,5が1行ずつ表示される。

繰り返しの為のリストを一々書くとめんどくさい。
組み込み関数の「range()」というものがある。

 range(10) → 「0,1,2,3,4,5,6,7,8,9」	# 0開始で、10が含まれないことに注意!
 range(5,10) → 「5,6,7,8,9」		# 5開始で、10は含まれない。
 range(1,100,10) → 「1,11,21,31,41,51,61,71,81,91」	# 増分を指定することもできる
 range(100,1-10) → 「100, 90, 80, 70, 60, 50, 40, 30, 20, 10」


!配列にインデックスでfor文を使う時の定番

range()とlen()を組み合わせる。

例:
 a = ['a', 'b', 'c', 'd']
 for x in range(len(a))
 	print a[x]	# 各項目への処理


!print文

pythonにもprint文がある。
デフォルトでは標準出力に書くらしい。
perlと違い、最後に改行される。


!!履歴
2008/10/31 -- import strictはガセネタだったらしい
2008/10/29 -- 初版

[[技術的雑談]]へ戻る

!!突っ込み
{{comment}}

[[技術的雑談]]へ戻る

{{trackback}}

[[技術的雑談]]へ戻る