「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。目下、データ分析・語学に力点を置いています。

MENU

Pythonをゆっくりていねいに学ぶ(その08/X)

 Pythonを真面目にゆっくり学ぶべく

を参考に学んでいきます*1

4. Pyの皮:コード構造

4.7 特殊な引数

4.7.8 無名関数:ラムダ関数

 ラムダ関数は、ひとつの文で表現される無名関数である。個々の関数を定義する方がコードが明確になる一方で、小さな関数を多数定義することになると管理が煩雑になる局面では、ラムダを用いると効果的である。

########################
### ラムダ関数の定義 ###
########################

### 以下の関数をラムダ関数として記述
def edit_story(words, func):
    for word in words:
        print(func(word))

stairs = ['thud', 'meow', 'thud', 'hiss']

def enlive(word):
    return word.capitalize() + '!'

edit_story(stairs, enlive)

# ラムダ関数:
edit_story(stairs, lambda word: word.capitalize() + '!')

4.8 ジェネレータ

 \mathrm{Python}のシーケンスを作成するオブジェクトをジェネレータという。ジェネレータがあれば、シーケンス全体を作ってメモリに格納しなくてもシーケンスを反復処理できる。

# ジェネレータの例:range()
sum(range(1,101))

 ジェネレータは反復処理のたびに最後に呼び出されたときにどこにいたかを管理し次の値を返す。
 大きくなる可能性があるシーケンスを作りたいが、ジェネレータ内包表記に収めるにはコードが大きすぎる場合は、ジェネレータ関数を書く。値を\mathrm{return}の代わりに\mathrm{yield}文で返す点が相違する。

########################
### ジェネレータ関数 ###
########################

def my_range(first = 0, last = 10, step = 1):
    number = first
    while number < last:
        yield number
        number += step

ranger = my_range(1, 5)
print(ranger)

for x in ranger:
    print(x)

4.9 デコレーター

 入力として関数を1つ取り別の関数を返す関数をデコレーターという。
 たとえば\mathrm{document_it}()は以下を行なう:

  • 関数名と引数の値を表示する
  • その引数を渡して関数を実行する
  • 結果を表示する
  • 実際に使うために変更後の関数を返す

他にも\mathrm{square_it}()は結果の二乗を返す。

###############################
### デコレーター(decorator) ###
###############################

### デコレーター
## 1. 手で定義
def document_it(func):
    def new_function(*arg, **kwargs):
        print('Running function:', func.__name__)
        print('Positional arguments:', arg)
        print('Keyword arguments:', kwargs)
        result = func(*arg, **kwargs)
        print('Result:',result)
        return result
    return new_function

# サンプル関数
def add_ints(a,b):
    return a + b

print(add_ints(3,5))

cooler_add_ints = document_it(add_ints)
cooler_add_ints(3,5)

# 2. デコレーター
@document_it
def add_ints(a, b):
    return a + b

add_ints(3,5)

4.10 名前空間とスコープ

 (変数の)名前はどこで使われるかによって異なるものを参照することができる。特定の名前の意味が一意に決まり他のそれとは無関係になる領域を名前空間という。
 プログラムのメイン部分ではグローバル名前空間を定義する。このときこの空間で定義された変数はグローバル変数という。
 グローバル変数の値は関数内から参照できる。

####################################
### グローバル変数とローカル変数 ###
####################################

# グローバル変数
animal = 'fruitbat'
def print_local():
    print('inside print_global: ', animal)
print('at the top level:', animal)

# グローバル変数をローカルで書き換えることは出来ない
def change_and_print_global():
    print('inside change_and_print_global:',animal)
    animal = 'wombat' # グローバル変数を
    print('after the change:', animal)

try:
    change_and_print_global()
except Exception as e:
    print(e)


###
# ローカル変数を書き換えることもできない
animal = 'fruitbat'
def change_local():
    animal = 'wombat'
    print('inside change_local:',animal, id(animal))

change_local()
print(animal)
print(id(animal))

animal = 'fruitbat'
def change_and_print_global():
    global animal
    animal = 'wombat'
    print('inside change_and_print_global:', animal)

print(animal)
change_and_print_global() # ここでグローバル変数のanimalの値を変更
print(animal)

*1:第2版が出ているものの初版しか持っていないのでこちらで。

プライバシーポリシー お問い合わせ