Python - 関数

関数

Python では def 文を用いて関数 (function) を定義することができます。関数を呼び出す際に情報を渡すためには引数 (パラメータ) と呼ばれるものを使います。以下の例では xy の2つの引数を受け取り、合計値を表示しています。

def add(x, y):
    print x + y

add(3, 5) # 8
def 文を用いた関数と2つの引数

return 文は、関数の戻り値を指定します。return 文を省略すると、関数は None を返します。

def add(x, y):
    ans = x + y
    return ans

n = add(3, 5)
print n # 8
return

位置引数

位置引数は、先頭から順に対応する位置の仮引数にコピーされる引数です。以下の例では位置引数から辞書を作って返します。

def menu(wine, entree, dessert):
    return {'wine': wine, 'entree': entree, 'dessert': dessert}

menu('chardonnay', 'chicken', 'cake')
# {'dessert': 'cake', 'wine': 'chardonnay', 'entree': 'chicken'}
位置引数

キーワード引数

引数には、キーワード引数を指定することができます。また、キーワード引数は関数定義側で、デフォルトの値を指定することができます。

def repeat_msg(msg, repeat=3):
    for i in range(repeat):
        print msg

repeat_msg('Hello')           # Hello, Hello, Hello
repeat_msg('Hello', repeat=5) # Hello, Hello, Hello, Hello, Hello
キーワード引数

* による位置引数のタプル化

引数の一部に * を使うと、残りの位置引数をタプルにまとめて引数にセットします。

def func(a1, a2, *args):
    print a1   # A
    print a2   # B
    print args # ('C', 'D')
    
func('A', 'B', 'C', 'D')
* による位置引数のタプル化

** によるキーワード引数の辞書化

引数の一部に ** を使うと、残りのキーワード引数を辞書にまとめて引数にセットします。

def func(a1, a2, **params):
    print a1     # A
    print a2     # B
    print params # {'k1': 'K1', 'k2': 'K2'}
    
func('A', 'B', k1='K1', k2='K2')
** によるキーワード引数の辞書化

位置引数をまとめる *args**params を併用する場合 *args**params の順序で並べなければなりません。

docstring

関数本体の先頭に文字列を組み込めば、関数定義にドキュメントを付けることができます。これを関数の docstring (ドキュメントストリング) と呼びます。一般的に docstring は、関数の説明文として使用されます。

def echo(anything):
    'echo は、与えられた入力引数を返す'
    return anything
docstring

関数の docstring を表示するには Python の help() 関数を呼び出します。関数名を渡すと、引数リストとともに整形された docstring が返されます。

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

echo(anything)
    echo は、与えられた入力引数を返す
docstring

整形前の docstring を表示する場合は、以下のようにします。

>>> print(echo.__doc__)
echo は、与えられた入力引数を返す
docstring

グローバル変数

関数の外部で定義された変数はグローバル変数として扱われます。関数の中でグローバル変数を参照することはできますが、代入することはできません。代入する場合は global で宣言する必要があります。

count = 0         # グローバル変数

def func():
    print count   # 参照することはできる
    global count  # global宣言してやれば
    count += 1    # 代入することもできる
グローバル変数

globals() はグローバル変数、locals() はローカル変数の一覧を辞書として返却します。

def func():
    for k in globals().keys():
        print "GLOBAL: %s = %s" % (k, globals()[k])
    for k in locals().keys():
        print "LOCAL: %s = %s" % (k, locals()[k])

func()
グローバル変数一覧とローカル変数一覧

無名関数:ラムダ関数

ラムダ関数は、名前のない小さな関数を定義します。ラムダ関数自体は式として扱われるため、関数の引数に指定することができます。

myfunc = lambda x, y: x + y
print myfunc(3, 5) # 8
ラムダ関数

ラムダ関数は sorted(), map(), filter() などの関数に渡す無名関数として利用されることがあります。

a = [1, 2, 3]
print map(lambda x: x ** 2, a) # [1, 4, 9]
グロラムダ関数

イテレータ

イテレータ (iterator) は for 文で使用できる繰り返し機能を持つオブジェクトです。イテレータオブジェクトは __iter__()next() メソッドを持つオブジェクトを返却します。next() メソッドは次の要素を返却し、最後に達すると StopIteration 例外を返します。

class MyClass:
    def __init__(self):
        self.data = (1, 2, 3, 4, 5)
        self.index = 0
    def __iter__(self):
        return self
    def next(self):
        if self.index < len(self.data):
            self.index += 1
            return self.data[self.index - 1]
        else:
            raise StopIteration

for n in MyClass():
    print n # 1, 2, 3, 4, 5
イテレータ

ジェネレータ

ジェネレータ (yield) は、シーケンスを作成するオブジェクトです。一般的に戻り値としてイテレータを返却する際にジェネレータが用いられます。

def funcB(list):
    for n in list:
        yield n * 2

for n in funcB([1, 2, 3, 4, 5]):
    print n # 2, 4, 6, 8, 10
ジェネレータ

ジェネレータの利点は、シーケンス全体を作ってメモリに格納しなくてもシーケンスを反復処理できることです。そのため、巨大なリストを処理する場合にメモリや処理効率が改善できます。例えば、巨大なファイルを読み込む場合、yield によるイテレータを用いた場合は1行分のメモリしか使用しません。

def readfile(f):
    for line in f:
        yield line.rstrip()

f = open("test.txt")
for line in readfile(f):
    if (line == "__END__"):
        break
    print line
f.close()
ジェネレータ

デコレータ

関数を実行する前後に特殊な処理を実行したい場合、デコレータ (@) を用いることができます。下記の例では hello() 関数を mydecolater でデコレート (装飾)しています。デコレーション関数では、関数実行前に start、関数実行後に end を出力しています。

def mydecolater(func):        # デコレータを定義する
    def wrapper():
        print "start"         # 前処理を実行する
        func()                # デコレート対象の関数を実行する
        print "end"           # 後処理を実行する
    return wrapper

@mydecolater
def hello():
    print "hello"

hello()                       # start, hello, end
デコレータ

関連記事

Python 全体の仕様を体系的にまとめたページは、プログラミング Python 入門を参照してください。

Category:
プログラミング
公開日:
更新日:
Pageviews:
25
Shares:
1
Tag:
Python
hatebu icon
hatebu