Author: satoshiokita
DATE:2006/08/27 TIME:19:30:47 JST
fliename: 00.py
とりあえず、BitTorrentのソースコードを見たい。
けど、Pythonをやった事がないので、基本的な文法を触ってみた。
fp_XXXXXというのは、関数型プログラミングをPythonでやったサンプルなので無視して、
それ以外を見れば、なんとなくPythonの雰囲気がつかめると思う。
説明面倒なので、とりあえず打ち込めば理解できるはず。
特徴は、
1.インデントでブロックを判断している
2.リスト、タプル、マップ(連想配列)の書き方を押さえる
3.関数を引数に渡せるようだ。
4.Class, Import,Module(パッケージの事)は、Javaと近い。
5.記号を極力使わないようにしているようだ。
1.のインデントでブロックを判断しているのは重要で、
if (x == 1):
などのようにコロンを制御文の最後に忘れない事。
あとは、BitTorrentをみていて感じたのが、記号がなくインデントが正確なおかげで
結構ソースコードが見やすかった。Perlユーザとかは、逆に打ち込むのが面倒になるかも。
fliename: comment.py
#!/usr/bin/python
# -*- encoding: utf-8 -*-
# コメントはPerlと同じ
print "日本語を表示するには、-*- encoding: xxx -*-を埋め込もう"
fliename: create_class.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# 引数のobjectは継承関係か?
class HogeClass(object):
# コンストラクタ
def __init__(self):
self.my_name = 'instantiage'
def __del__(self):
self.my_name = ''
# クラス内のメソッドは、第一引数がselfじゃないとインタプリタが怒る
def set_my_name(self, arg_name):
self.my_name = arg_name
def print_name(self):
print self.my_name
# これで型表示
print HogeClass
# オブジェクトの生成
print HogeClass()
testObj = HogeClass()
print testObj
testObj.set_my_name("aaa")
testObj.print_name()
fliename: exception.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
testval = 0
assert testval == 0, "print this message"
def add():
print "add function"
raise "TestException"
try:
add()
except "TestException":
print "TestException exec"
fliename: for.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# C言語などの繰り返し処理をするときは、組み込みのxrangeまたはrangeを使う。
for i in xrange(5):
print i
# C言語の場合
# for (int j = 0; j < 6; j +=2 )
# print j;
#
for j in xrange(0,6,2):
print j
# Pythonの繰り返し処理は、データがあるリストなどの要素に対して処理をする事が
# みてとれる。そのためデータ構造に問題がない限り、処理が停止する事はない。
# C言語は、ポインタの操作などでき、データ構造に依存しない事が分かる。
# いろいろな組み込みデータ構造
str_list = ['Apple','Banana','Orange'] # リストはデータ変更が可能
str_tuple= ('Beer' ,'Coffee','Tea') # タプルはデータ変更が不可能
str_map = {1: 'O', 2: 'T', 3: 'T'} # マップはkey:value,で区切る
# マップは、どんなオブジェクトでもキーに出来るようだ。
str_map2 = {
"P": 'Python',
"J": 'Java',
"C": 'C'}
for item in str_list:
print item
for item in str_tuple:
print item
for item in str_map:
print str_map[item]
for item in str_map2:
print str_map2[item]
fliename: fp_short_circuit.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# fp(Function Programming) 関数型プログラミング
# if文をなくしてみる
x = 1
def p(x):
return x
# 普通のif分岐
# char s = null;
# if ( x == 1 ) {
# s = ('1');
# } else if {
# s = p('2');
# } else {
# s = p('3');
# }
# prinf("%c", s);
#
# ショートサーキットの例
print ( x== 1 and p('1')) or ( x==2 and p('2')) or (p('3'))
fliename: fp_while_loop.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# fp(Function Programming) 関数型プログラミング
# refer:
# http://www-06.ibm.com/jp/developerworks/linux/010615/j_l-prog.html
# while 1 == 1:
# print "hello"
# if (x == 2):
# break;
# else:
# print "error"
#
def while_(x):
print "hello"
if ( x == 2 ):
return 1
else:
return 0
x = 2
while_FP = lambda: ( 1 == 1 and while_(x)) or while_(x)
while_FP()
# 一般の制御フローでの演算
# ちゃんと動くかテスト
bigmuls = []
for x in (1,2,3,4):
for y in (10,15,3,22):
if (x*y > 25):
bigmuls.append((x,y))
print bigmuls
def extream_exp1(xX, yY):
bigmuls = []
for x in xX:
for y in yY:
if (x*y > 25):
bigmuls.append((x,y))
return bigmuls
print "extream_exp1 begin"
print extream_exp1((1,2,3,4),(10,15,3,22))
print "extream_exp1 end"
# 関数プログラミングでの同様な式
# ちゃんと動くかテスト
print [(x,y) for x in (1,2,3,4) for y in (10,15,3,22) if (x*y > 25)]
# lambdaキーワードを使って関数化
extream_exp2 = lambda xX, yY: [(x,y) for x in xX for y in yY if (x*y > 25)]
# 関数のテスト
print "extream_exp2 begin"
print extream_exp2((1,2,3,4),(10,15,3,22))
print "extream_exp2 end"
fliename: fp_while_loop2.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# fp(Function Programming) 関数型プログラミング
# 組み込み関数raw_inputのテスト
val = raw_input('prompt>')
print val
def echo_():
while 1:
x = raw_input("prompt2>")
if ( x == 'quit' ):
break
else:
print x
# quitを入力するまでプロンプトを出しつづける
echo_()
# Pythonでは、戻り値をprint関数から取る事が出来ないので(val = print "hello")
# ダミーのpr関数を作る。これは単純に値を表示して、引数を戻り値で返す。
# 関数型プログラミングは値を返せるという事が重要なのが次の繰り返し処理で分かる
def pr(x):
print x
return x
# 関数プログラミングで同じ事を行う。
# もし、quit文字列を入力しない場合は、echo_fp関数を呼ぶ。それでecho_fp関数というのは
# はじめに、lambdaキーワードで定義した式の事なので、この一行で再帰処理を実現している。
echo_fp = lambda: pr(raw_input("prompt3>")) == "quit" or echo_fp()
# 実行
echo_fp()
# ここで分かる重要なポイントは、もしpr関数がはじめからあった場合、つまりPythonではなく
# Lispなどの関数型言語の場合当然あるので、
#
# 変数を定義しない事になる。
#
# 一般にプログラミングをすると変数が少なくなればなるほど、その関数内で複数の処理をしていない.または変数のデータのやり取り時をコーディングしている上でのバグを引き起こす原因を防ぐ
# かつ、その小さい関数の再利用化を推し進める可能性がある。
#
# こうしてみると、オブジェクト志向は、肥大化するソースコードに対して、データと処理を
# 分離してさらに、パッケージやクラスなどの分類する粒度を複数作る事で可読性と管理を
# 容易にする方向性があるが、関数型言語は、逆に肥大させない方法に視点を置き、それを防ぐ
# には、変数や、文法をどのようにすればよいかを考察しているようにみえる。
#
fliename: func.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
#
# 定数がいくつかあるようだ。
print __name__
if __name__ == '__main__':
print "__name__定数の値は" + __name__ + "らしい"
# Pythonでは、関数はdefで定義して、{}やendなど終了する文字を書かない
def printHello():
print "HELLO"
printHello()
fliename: hello.py
#!/usr/bin/python
print "hello world"
fliename: if.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# 制御文の後にセミコロンが必要なのが他の言語と違う
val = -1
if val == 1:
print "if exec"
elif val <= -1:
print "elif exec1"
elif val >= 2:
print "elif exec2"
else:
print "else exec"
strval = "HELLO"
if val != "GOODBYE":
print strval
fliename: import.py
#!/usr/bin/python
# パッケージはimport文で読み込む。
# sysパッケージがはじめからあるらしい。
import sys
try:
import hogehoge
except:
print 'cannot hogehoge package'
sys.exit(1)
fliename: import2.py
#!/usr/bin/python
# パッケージではなく、モジュールというらしいは、import文で読み込む。
# sysモジュールがはじめからあるらしい。
import sys
# Javaと似ている.
# from ディレクトリ名.ファイル名 import クラス名(モジュール?)
# aadirディレクトリにあるfuga.pyというファイル名のHogeクラスを呼び出す.
from aadir.fuga import Hoge
sys.exit(1)
# ライブラリはこれで読み込めるので、後はPythonのライブラリを検索エンジンで調べて
# つかってみよう。
fliename: lambda.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
#
# lambdaキーワードで無名関数を作る事が出来る。
# Ruby言語などはクロージャと読んでいる。
# Java言語では無名関数と読んでいる。
# 簡単なサンプル。
y = lambda x: x**2
print y
print y(5)
# 上記の例では、普通の関数を作成するのと変わりない。
# mapデータ構造を使った例。
# mapの第2引数は、リストやタプルのように繰り返しされるデータでなければいけないので
# リストを代入して、リストを一気に演算する。
# C言語などのようにある程度歴史がある言語の文法と比較すると利便性がある。
# また、関数プログラミングを行う場合に良いようだ。
test_ary = [ 1, 2, 3, 4, 5 ]
ans = map(lambda x: x**2, test_ary)
print ans
# リストのデータに関数を詰め込んでみる
func_ary = [
lambda x: x + x,
lambda x: x - x,
lambda x: x * x,
lambda x: x / x ]
print func_ary[0](5) # x + x
print func_ary[1](5) # x - x
# for文というか、繰り返し処理や再帰処理を組み合わせる事でかなり強力になりそうな予感が
# する。
# こういう複数の処理を作る事は出来ないようである。
z = lambda x:
print "hello"
print x + 2
print "hogehoge"
fliename: lambda2.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
#
# こういう複数の処理を作る事は出来ないようである。
#z = lambda x:
# print "hello"
# print x
# print "hogehoge"
# Javaでいう無名メソッド、Rubyでいうクロージャのように使えるのかとおもったのだが。。。
# それで、処理を複数加える場合は、
def func1(x):
print "hello"
print x
def func2(x):
print "hogehoge"
# 普通に呼ぶ場合、
func1(1)
func2('dummy')
# こういう呼び方やmapなど
l_ary = [func1,func2]
for f in l_ary:
f(1)
# mapをつかった応用
z_map = map(func1, [1,2,3,4,5])
# 実行
z_map
# これだけだと、どういう時に使うか分からないが将来応用できそうな予感がある
fliename: variable.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
# pythonは、スワップ処理が直ぐ出来る。
x = 1
y = 2
print x , y
# こんな感じ
y, x = x, y
print x , y
fliename: while.py
#!/usr/bin/python
# -*- encoding:utf-8 -*-
cnt = 0
while cnt < 10:
print cnt
cnt += 1
# cnt++
# ++演算子は使えない
# はじめからTrueとFalseというブール値が使える
my_bool = True
while my_bool:
print "HELLO"
my_bool = False
null_string = 'DUMMY..'
while null_string:
print "HOGE"
null_string = ''