だいたい7分ぐらいで Python の基本的なこと


Pythonとは


こんな感じのソースになります。

def fib(n):
    """Print a Fibonacci series up to n."""
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

fib(2000)

コメント

コメントは # から行末まで。複数行コメントは存在しません。

# これはコメント
print "hoge"    # これもコメント

演算子

普通に使えます。論理演算には「and」「or」「not」を使います。
あと、整数の割り算で商を得る(フロア演算)には「//」という演算子を使います。
以下のような多重代入も可能です。

x = y = z = 0

文字列リテラル

文字列リテラルはシングルクオートまたはダブルクオートにて指定します。文字列は不変オブジェクトです。

'spam egg'  # 文字列リテラル
"spam egg"  # 文字列リテラル


トリプルクオート("""または''')で定義すると複数行を改行記号のエスケープなしに扱えます。

print("""Hello
     python""")

以下の出力となる。

Hello
    python


row 文字列は以下の定義で改行記号などがそのまま文字として扱われます。正規表現を使う時に便利です。

hello = r"hello \n world"
print(hello) # hello \n world と出力される

文字列の連結

+ 演算子で結合可能です。隣接する2つの文字列は自動的に連結されます。

hello1 = 'hello ' + 'world'
print(hello1)  # "hello world"

hello2 = 'hello ' 'world'
print(hello2)  # "hello world"

* 演算子で繰り返しも可能です。

hello = 'hello ' * 3 + 'world'
print(hello)  # "hello hello hello world" となる

文字列のスライス

文字列は添字付けにてスライスが可能です。

hello = 'World'
hello[0:2]  # Wo
hello[2:4]  # rl
hello[4]    # d

インデックス値を省略した場合、1つ目はデフォルトが0、2つ目は文字列のサイズとなります。

hello[:2]  # Wo
hello[2:]  # rld

インデックスに負数を指定した場合は、右から数える指定となります。

リスト

最も良く使います。文字列と同じようにインデックスにてスライスできます。

a = ['spam', 'eggs', 100, 999]
a[1]    # 'eggs'を示す
a[1:3]  # ['eggs', 100]を示す

文字列とは違いリストは変更できます(ミュータブルです)。代入、追加やスライスへの代入もできます。

a[2] = 88       # ['spam', 'eggs', 88, 999]となる
a + ['Foo']     # ['spam', 'eggs', 88, 999, 'Foo'] となる
a[0:2] = [1,2]  # [1, 2, 88, 999]となる

タプル

タプルは不変オブジェクトであり、値をカンマで区切ることで定義します。

t = 12345, 54321, 'hello!'
t[2]  # 'hello!'

入れ子にすることもできます。

u = t, (1, 2, 3, 4, 5)
# ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) となる

タプルは以下のように各変数への一発代入ができます。シーケンス・アンパッキングと言います。

t = 12345, 54321, 'hello!'
x, y, z = t   # シーケンス・アンパッキング


要素が空のタプルと要素が1つのタプルは以下の様に定義します。

empty = ()    # 空のタプル
t = 'hello',  # 要素が1つのタプル 

Set

集合は{}にて定義します。

basket = {'apple', 'orange', 'apple', 'orange'}
# 重複が削除され {'orange', 'apple'} となる

set()関数による定義も可能です。

basket = ['apple', 'orange', 'apple', 'orange']
a = set(basket) # 重複が削除され {'orange', 'apple'} となる

in により含まれるかの判定ができます。

'orange' in basket     # True
'crabgrass' in basket  # False

ディクショナリ

ハッシュやマップと呼ばれるものと同様です。Set の要素に「キー:値」を入れる形で定義します。

tel = {'jack': 4098, 'sape': 4139}
tel['guido'] = 4127  # {'sape': 4139, 'guido': 4127, 'jack': 4098}

要素の削除は del で削除できます。

del tel['sape']

dict コンストラクタにてディクショナリを定義することもできます。

dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])

if文

以下の通り見たままです。

if x < 0:
    print('負数');
elif x == 0:
    print('ゼロ');
else:
    print('整数');

for文

リストや反復子などを foreach する記述となります。

animal = ['cat', 'dog', 'monky']
for x in animal:
    print(x, len(x))

ループ周りでは、break や continue 、whileもあり、Cなどと同様です。


指定回数ループさせるには range を使います。

for i in range(4):
    print(i)

この例では 0, 1, 2, 3 とループすることになります。
range は、range(2, 10, 3) のように 2 から 10 まで 3 刻みでのように指定できます。


ループには else 節を指定できます。リストを使い果たした場合に実行され、break 文で終了した場合には実行されません。

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, 'equals', x, '*', n//x)
            break
    else:
        # ループで約数を見つけられなかった
        print(n, 'is a prime number')

関数定義

関数は def にて定義します。見たままに 関数名(引数) です。

def fib(n):
    """Print a Fibonacci series up to n."""
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

2行目のトリプルクオートは docstring でドキュメンテーションツールに利用されます。ビルトイン関数の help() を使うと以下のようにドキュメントが参照可能です。

>>> help(fib)
Help on function fib in module __main__:

fib(n)
    Print a Fibonacci series up to n.


関数からは return にて値を返却できます。

def ask_ok(prompt, complaint='Yes or no, please!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        print(complaint)

また、上記では complaint という引数にデフォルト値を指定しており、呼び出し時に省略可能となります。

ask_ok('Yes or no :')


呼び出し元では、普通に引数を渡すほか、キーワード引数も使えます。

ask_ok('Yes or no :', 'Yes or no, please!')
ask_ok(complaint='Yes or no, please!', prompt='Yes or no :')


以下のような関数定義は、2つ目の引数でタプルを受け取り、3つ目の引数ではディクショナリを受け取ります。

def cheeseshop(kind, *arguments, **keywords):
    for arg in arguments: print(arg)
    keys = sorted(keywords.keys())
    ・・・

以下のように可変長の引数を渡すことができます。

cheeseshop("Limburger",
           "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

"It's very runny, sir."と"It's really very, VERY runny, sir."がタプルとして渡され、それ以降がディクショナリとして渡されます。

引数のアンパック

引数にはリストやタプルなどに *演算子 を付けることでアンパックして呼び出すことができます。

args = [3, 6]
list(range(*args))  # list(range(3, 6))と同じ

ディクショナリについては **演算子により同様にアンパックできます。

内包表現

リストや集合、ディクショナリには要素を簡素に作成する内包表現ができます。
リスト内包は for 節にて以下のように定義します。

vec = [2, 4, 6]
[3*x for x in vec] # [6, 12, 18] となる

さらにif節を使うことで条件を指定できます。

[3*x for x in vec if x > 3]  # [12, 18]


セット内包とディクショナリ内包も同様に以下のように書けます。

s = {x for x in 'abracadabra' if x not in 'abc'}
# s は {'r', 'd'} となる

d = {x: x**2 for x in (2, 4, 6)}
# d は {2: 4, 4: 16, 6: 36} となる

例外

例外を投げるには raise を使います。

raise NameError('HiThere')

例外のキャッチは以下のように try 〜 except で処理します。

try:
    ・・・
except IOError as err:
    print("I/O error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

except では以下のように複数例外をまとめて扱うこともできます。

except (RuntimeError, TypeError, NameError):


for ループにもあったように else 節を例外処理に定義できます。

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    else:
        print("result is", result)
    finally:
        print("executing finally clause")

else節 は try節 が例外無く終了した場合に実行されます。finally節については例外が起きても起きなくても必ず実行されます。

クラス

クラスは他の言語と同じように class にて定義します。

class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

定義したクラスのインスタンス化には new は不要です。以下のようにすることでインスタンス化されます。

x = MyClass()  # インスタンス化
x.f()          # メソッド実行

MyClass のメソッドは def f(self): とありますが、self はクラス自身のオブジェクトを表し、呼び出し側で指定する必要はありません。


メソッドには別名を付けてアクセスすることもできます。

x = MyClass()
xf = x.f
xf()

クラスのカプセル化

クラスの属性(メンバ)やメソッドは通常 public で外部から自由にアクセス可能です。またメソッドは全て virtual でサブクラスでオーバーライド可能です。
プライベート変数を用意するには変数の頭に _ を付けることでAPIの非公開部分であることを紳士的に定義します。
変数の頭に __spam の様にアンダースコアを2つ付けると _クラス名__spam のように字句的に置き換えられ、アクセス制御に使用することができます。

オブジェクトの初期化

クラスのインスタンス化時にオブジェクトを初期化するには、__init__ という特殊メソッドを使います。

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5) # インスタンス化

継承

クラスの継承はクラス名の後に(基底クラス)として定義します。

class base():
    def a(self):
        print('base a')

class sub(base):
    def a(self):  # オーバーロード
        print('sub  a')

基底クラスのメソッドをコールする「BaseClassName.methodname(self, arguments)」という簡単な方法が提供されている。


多重継承もサポートされており、以下のように基底クラスを複数指定します。

class DerivedClassName(Base1, Base2, Base3):

多重継承の場合は、深度優先で左から右の順で継承されるため、属性の検索は、Base1 → Base1の親 → Base2 → ・・ となります。

モジュール

ファイルを「モジュール名.py」としてモジュールとすることができます。fibo.py というファイルに以下の関数があった場合、

def fib(n):
    ・・・

def fib2(n):
    ・・・

以下のようにすることでモジュールをインポートして使用できます。

import fibo

fibo.fib(100)

fib = fibo.fib
fib(100)

モジュールは以下の様に直接取り込む事もできます。

from fibo import fib, fib2

fib(100)


モジュールの検索は、カレントディレクトリ→環境変数PYTHONPATHで指定されたディレクトリの順で検索されます。
ディレクトリを階層化することでパッケージとして扱うこともできます。「sound/efects/echo.py」というディレクトリ階層は、以下のようにインポートします。

import sound.efects.echo

この再には、各ディレクトリに __init__.py というファイル(空ファイルで良い。初期化のためのコードを含ませることもできる)を配置する必要があります。





入門 Python 3

入門 Python 3