Program学習 Python

Pythonの基礎③(関数応用:クロージャ/デコレータ/ラムダなど)

Program学習

Python基礎的な使い方について忘れ気味だったので自分ようにメモを残しておきます。

少し規模が大きいシステムではデコレータやラムダを使ってすっきり記載することができます。

Python関数応用:クロージャ/デコレータ/ラムダなど

関数内関数

・関数内部で利用するだけの関数

def outer(a, b):
    def plus(c, d):
        return c + d

    r1 = plus(a, b)
    r2 = plus(b, a)
    print(r1 + r2)

outer(1, 2)

// 結果
6

クロージャー

・後ほど実行したい関数などで利用
・関数のオブジェクトをリターンする

def outer(a, b):

    def inner():
        return a + b

    return inner
    
print( outer(1,2))

// 結果 inner関数のオブジェクト
<function outer.<locals>.inner at 0x00000246129DE700>

--------------------------------
f = outer(1,2)
r = f()
print(r)

// 結果
3
def circle_area_func(pi):
    def circle_area(radius):
        return pi * radius * radius

    return circle_area

ca1 = circle_area_func(3.14)
ca2 = circle_area_func(3.141592)

print(ca1(10))
print(ca2(10))

// 結果
314.0
314.1592

デコレータ

・関数の前後などで決まった動作をしたい場合に利用
・1回デコレータを作れば、多くの関数から利用することができる

// 第1段階
def add_num(a, b):
    return a + b

print('start')
r = add_num(10, 20)
print(r)
print('end')

// 結果
start
end
30

---------------------------------------
// 第2段階
def print_info(func):
    def wrapper(*args, **kwargs):
        print('start')
        result = func(*args, **kwargs)
        print('end')
        return result
    return wrapper

def add_num(a, b):
    return a + b

f = print_info(add_num)
r = f(10,20)
print(r)

// 結果
start
end
30

---------------------------------------
// 第3段階
def print_info(func):
    def wrapper(*args, **kwargs):
        print('start')
        result = func(*args, **kwargs)
        print('end')
        return result
    return wrapper

@print_info
def add_num(a, b):
    return a + b

r = add_num(10, 20)
print(r)

・デコレータは2つ以上設定できる

def print_more(func):
    def wrapper(*args, **kwargs):
        print('func:', func.__name__)
        print('args:', args)
        print('kwargs', kwargs)
        result = func(*args, **kwargs)
        print('result:',result)
        return result
    return wrapper

def print_info(func):
    def wrapper(*args, **kwargs):
        print('start')
        result = func(*args, **kwargs)
        print('end')
        return result
    return wrapper

@print_info
@print_more
def add_num(a, b):
    return a + b

r = add_num(10, 20)
print(r)

// 結果
start
func: add_num
args: (10, 20)
kwargs {}
result: 30
end
30

ラムダ

・Lamdaを使うことで簡単な関数などを1行で記載できる。

l = ['Mon', 'tue', 'Wed', 'Thu', 'fri', 'sat', 'Sun']

// lambdaを使わない場合:関数Functionを受け取って処理する
def change_words(words, func):
    for word in words:
        print(func(word))

def sample_func(word):
    return word.capitalize()

change_words(l, sample_func)

//結果
Mon
Tue
Wed
Thu
Fri
Sat
Sun
-----------------------------------------

// lambdaを使った場合の書き方(1)
sample_func = lambda word: word.capitalize()
change_words(l,sample_func)

// lambdaを使った場合の書き方(2/3)
change_words(l,lambda word: word.capitalize())
change_words(l,lambda word: word.lower())

ジェネレーター

・ジェネレーターは、通常の関数の、return文をyieldに置き換えたもの
・ジェネレーターは呼び出されるたびに、行われた処理を記憶、ステートをもつ
・nextで順番に値を取得できる


l = ['Good morning', 'Good afternoon', 'Good night']

for i in l:
    print(i)

print("################")

def greeting():
    yield 'Good morning'
    yield 'Good afternoon'
    yield 'Good night'
    
for g in greeting():
    print(g)

// 結果
Good morning
Good afternoon  
Good night      
################
Good morning    
Good afternoon  
Good night 


--------------------------------------------
def greeting():
    yield 'Good morning'
    yield 'Good afternoon'
    yield 'Good night'

g = greeting()
print(next(g))
print("@@@@@@@@@@")
print(next(g))
print("@@@@@@@@@@")
print(next(g))

// 結果
Good morning
@@@@@@@@@@
Good afternoon
@@@@@@@@@@
Good night

・一度に処理しなくてもより場合などには有効
・yieldで返すアイテムがなくなるとエラーになる

def counter(num=10):
    for _ in range(num):
        yield 'run'


def greeting():
    yield 'Good morning'
    yield 'Good afternoon'
    yield 'Good night'

g = greeting()
c = counter()

print(next(g))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))

print(next(g))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))

// 結果
Good morning
run
run
run
run
run
Good afternoon
run
run
run
run
run
Traceback (most recent call last):
  File "c:\PythonProject\aaaaaa.py", line 29, in <module>
    print(next(c))
StopIteration

Pythonのオススメ勉強方法

私がオススメするPythonの効果的な学習方法は「Udemy(ユーデミー)」によるビデオ学習です。

「Udemy」は、オンライン学習の提供サイトです。学びたい人は多くある講座の中から受講したいコースを選択することができ、動画で学べるのが特徴です。

多くあるPythonのコースの中でもオススメするPythonのコースは以下となります!!

現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル

このコースでは合計で28.5時間のビデオ講座があって、それらを受講するだけで、Pythonの基礎から応用まで学ぶことができます。

私も購入して受講していますが、内容としては初心者の方から上級者まで対応する幅広い内容になっています。

下手な書籍を何冊か購入するより、この動画コースを最初からじっくりと受けることで総合的なスキルを習得することができるできます。おそらくこれ以上の教材はないと思いますので、絶対おすすめです。

ちなみに、Udemyでは頻繁にセール(1か月に2,3回程度)が開催されているので、セールのタイミングで購入すれば90%OFFになる講座もあるため、セールが開催されてからの購入をオススメします!

今回は以上となります。

コメント

タイトルとURLをコピーしました