def【関数定義】3.5・3.8
return【関数の戻り値】3.8
lambda【ラムダ式 (無名関数)】

def【関数定義】3.5・3.8

メモ 構文
引数の種類 デコレータ ジェネレータ関数 関数の呼び出し クラスメソッド・静的メソッド 特殊属性

メモ

  • 関数・メソッドの定義
  • 関数の呼び出し
  • クラスメソッド・静的メソッド
    デコレータに下記を指定
  • 特殊属性
    属性備考
    __annotations__辞書型アノテーション
    引数キー:引数名
    戻り値キー:"return"
    __closure__タプルクロージャで参照する自由変数等
    __closure__[n].cell_contents上記自由変数等の個々の値
    __code__オブジェクトコードオブジェクト
    __defaults__タプルデフォルト値
    __dict__辞書型
    マッピングオブジェクト
    属性
    __doc__文字列ドキュメンテーション文字列
    __globals__辞書型関数のグローバル変数
    __kwdefaults__辞書型キーワード引数のデフォルト値
    __module__文字列モジュール名
    __name__文字列関数名
    __qualname__ 3.3文字列関数パスへのドット名表記

構文

[@ デコレータ名 (複数:新規行)]
def 関数名([引数 (複数:カンマ区切り)][,])[->戻り値アノテーション]: 関数処理1 (1行)
関数処理2 (複数行可)

デコレータ名nドット (.) 指定可能
引数
引数位置引数 ( のみで呼び出し可)
*引数 (タプル型)可変長引数・可変長位置引数 (通常 *args 使用)
引数キーワード引数 (位置引数より後に定義:引数= で呼び出し)
**引数 (辞書型)可変長キーワード引数 (通常 **kwargs 使用)
* のみ可変長引数を使用せずキーワード引数との区切りとして指定 (これより後は、キーワード引数としてのみ有効) 〔/ のみこれより前は、位置引数としてのみ有効 3.8引数 = デフォルト値デフォルト値指定
引数: 引数アノテーション引数アノテーション指定
関数処理n (どちらか1つを指定)関数の処理

# 引数なし・デフォルト値
def func_0():
    print("func_0()")

func_0()

def func_2(p1, p2 = 2):
    print("func_2", p1, p2)

func_2(10, 20)
func_2(100)
func_2(p2 = 22, p1 = 11)
【出力例】
func_0()
func_2 10 20
func_2 100 2
func_2 11 22
# 各種引数 (1/3)
def func_args(p1, p2, *args, p11 = 110, p12 = 120, **kwargs):
    print(p1, p2, args, p11, p12, kwargs)
    print("args =", end=" ")
    for arg in args:
        print(arg, end=" ")
    print()
    print("kwargs =", end=" ")
    for kw in kwargs:
        print(kw, kwargs[kw], end=" ")
    print("\n")

func_args("a", 2)
func_args("b", 2, 3)
func_args("c", 2, 3, 4, p11=11, p12=12)
func_args("d", 2, 3, 4, p101=101, p102=102)
func_args("e", 2, 3, 4, p11=11, p12=12, p101=101, p102=102)
【出力例】
a 2 () 110 120 {}
args = 
kwargs = 

b 2 (3,) 110 120 {}
args = 3 
kwargs = 

c 2 (3, 4) 11 12 {}
args = 3 4 
kwargs = 

d 2 (3, 4) 110 120 {'p101': 101, 'p102': 102}
args = 3 4 
kwargs = p101 101 p102 102 

e 2 (3, 4) 11 12 {'p101': 101, 'p102': 102}
args = 3 4 
kwargs = p101 101 p102 102 

# 各種引数 (2/3)
def func_args2(p1, p2, *, p11 = 11, p12 = 12):
    print(p1, p2, p11, p12)

func_args2("a", 2)
func_args2("b", 2, p11=110, p12=120)
# func_args2("c", 2, 3, 4)  # TypeError
【出力例】
a 2 11 12
b 2 110 120
# 各種引数 (3/3) Python 3.8
def func_args31(p1, p2, p11=11, p12=12):
    print(p1, p2, p11, p12)

def func_args32(p1, p2, /, p11=11, p12=12):
    print(p1, p2, p11, p12)

def func_args33(p1, p2, /, p11=11, p12=12, *, p21=21, p22=22):
    print(p1, p2, p11, p12, p21, p22)

func_args31("P1", "P2")
# 出力:P1 P2 11 12
func_args32("P1", "P2")
# 出力:P1 P2 11 12
func_args33("P1", "P2")
# 出力:P1 P2 11 12 21 22

func_args31("P1", p2="P2")
# 出力:P1 P2 11 12
#func_args32("P1", p2="P2")  # TypeError 例外
#func_args33("P1", p2="P2")  # TypeError 例外

func_args31("P1", "P2", "P11", "P12")
# 出力:P1 P2 P11 P12
func_args32("P1", "P2", "P11", "P12")
# 出力:P1 P2 P11 P12
func_args33("P1", "P2", "P11", "P12")
# 出力:P1 P2 P11 P12 21 22

func_args31("P1", "P2", p12="P12", p11="P11")
# 出力:P1 P2 P11 P12
func_args32("P1", "P2", p12="P12", p11="P11")
# 出力:P1 P2 P11 P12
func_args33("P1", "P2", p12="P12", p11="P11")
# 出力:P1 P2 P11 P12 21 22

func_args33("P1", "P2", "P11", "P12", p22="P22", p21="P21")
# 出力:P1 P2 P11 P12 P21 P22
func_args33("P1", "P2", p22="P22", p21="P21", p12="P12", p11="P11")
# 出力:P1 P2 P11 P12 P21 P22
#func_args33("P1", "P2", "P11", "P12", "P21")  # TypeError 例外
# 呼び出し (1/2) アンパック
def func_unpack(p1, p2, p3, p4, p5, p6):
    print(p1, p2, p3, p4, p5, p6)

p2 = [2, 3]
p5 = {"p5": 5, "p6": 6}
func_unpack(1, *p2, 4, **p5)
# 出力:1 2 3 4 5 6
# 呼び出し (2/2)
def func_call(p1, p2=2):
    print(p1, p2)
    
func_call("P1", "P2", )
# 出力:P1 P2

func_call("P1", )
# 出力:P1 2

#func_call("P1", (p2)="P2")  # Pyhon 3.8 構文エラー
# デコレータ (1/2)
def trace(func):
    def trace_inner(*args):
        print("Trace:Start", func.__name__, args)
        result = func(*args)
        print("Trace:End", func.__name__)
        return result  # 処理結果の返却

    return trace_inner  # 関数の返却


@trace
def print_str(s):
    print(s)

print_str("xyz")


def trace2(func):
    def trace2_inner(*args):
        print("Trace2:Start", func.__name__, args)
        result = func(*args)
        print("Trace2:End", func.__name__)
        return result  # 処理結果の返却

    return trace2_inner  # 関数の返却


@trace
@trace2
def print_str2(s):
    print(s)


print()
print_str2("XYZ")
【出力例】
Trace:Start print_str ('xyz',)
xyz
Trace:End print_str

Trace:Start trace2_inner ('XYZ',)
Trace2:Start print_str2 ('XYZ',)
XYZ
Trace2:End print_str2
Trace:End trace2_inner
# デコレータ (2/2)
def trace_outer(start, end):
    def trace(func):
        def trace_inner(*args):
            print("Trace:Start", func.__name__, args)
            print("start = '" + start + "' end = '" + end + "'")
            result = start + func(*args) + end  # 処理結果の変更
            print("Trace:End", func.__name__)
            return result  # 処理結果の返却

        return trace_inner  # 関数の返却

    return trace  # 関数の返却


@trace_outer("( ", " )")
def func_user(s):
    return "< " + s + " >"


print(func_user("xyz"))


def trace2_outer(start, end):
    def trace2(func):
        def trace2_inner(*args):
            print("Trace2:Start", func.__name__, args)
            print("start = '" + start + "' end = '" + end + "'")
            result = start + func(*args) + end  # 処理結果の変更
            print("Trace2:End", func.__name__)
            return result  # 処理結果の返却

        return trace2_inner  # 関数の返却

    return trace2  # 関数の返却


@trace_outer("(1 ", " 1)")
@trace2_outer("[2 ", " 2]")
def func_user2(s):
    return "<< " + s + " >>"


print()
print(func_user2("XYZ"))
【出力例】
Trace:Start func_user ('xyz',)
start = '( ' end = ' )'
Trace:End func_user
( < xyz > )

Trace:Start trace2_inner ('XYZ',)
start = '(1 ' end = ' 1)'
Trace2:Start func_user2 ('XYZ',)
start = '[2 ' end = ' 2]'
Trace2:End func_user2
Trace:End trace2_inner
(1 [2 << XYZ >> 2] 1)
# アノテーション
def func_annotation(
        p1: "引数1アノテーション",
        p2: "引数2アノテーション" = 20,) -> "戻り値アノテーション":
    print(p1, p2)
    return p1 + p2

print(func_annotation.__annotations__)
【出力例】
{'p1': '引数1アノテーション', 'p2': '引数2アノテーション', 'return': '戻り値アノテーション'}
# 特殊属性 (1/2)
def func_attribute(
        p1: "引数1アノテーション" ,
        p2: "引数2アノテーション" = 20,
        *p3: "引数3アノテーション",
        p4: "引数4アノテーション" = 40,
        **kwargs: "引数5アノテーション") -> "戻り値アノテーション":
    """ドキュメンテーション文字列"""
    def func_inner():
        print("func_inner.__name__=", func_inner.__name__)
        print("func_inner.__qualname__ =", func_inner.__qualname__)

    func_inner()
    return p1 + p2

print("func_attribute.__annotations__ =", func_attribute.__annotations__)
print("func_attribute.__closure__ =", func_attribute.__closure__)
print("func_attribute.__code__ =", func_attribute.__code__)
print("func_attribute.__defaults__ =", func_attribute.__defaults__)
print("func_attribute.__dict__ =", func_attribute.__dict__)
print("func_attribute.__doc__ =", func_attribute.__doc__)
print("func_attribute.__globals__ =", func_attribute.__globals__)
print("func_attribute.__kwdefaults__ =", func_attribute.__kwdefaults__)
print("func_attribute.__module__ =", func_attribute.__module__)
print("func_attribute.__name__ =", func_attribute.__name__)
print("func_attribute.__qualname__ =", func_attribute.__qualname__)
func_attribute(1, 2)
【出力例】
func_attribute.__annotations__ = {'p1': '引数1アノテーション', 'p2': '引数2アノテーション', 'p3': '引数3アノテーション', 'p4': '引数4アノテーション', 'kwargs': '引数5アノテーション', 'return': '戻り値アノテーション'}
func_attribute.__closure__ = None
func_attribute.__code__ = <code object func_attribute at 0x~, file "~.py", line ~>
func_attribute.__defaults__ = (20,)
func_attribute.__dict__ = {}
func_attribute.__doc__ = ドキュメンテーション文字列
func_attribute.__globals__ = {'__name__': '__main__', '__doc__': None, ~}
func_attribute.__kwdefaults__ = {'p4': 40}
func_attribute.__module__ = __main__
func_attribute.__name__ = func_attribute
func_attribute.__qualname__ = func_attribute
func_inner.__name__= func_inner
func_inner.__qualname__ = func_attribute.<locals>.func_inner
# 特殊属性 (2/2)
def func_closure():
    data_1 = []
    data_2 = []

    def func_inner():
        n = len(data_1) + 1
        data_1.append(n)
        data_2.append(n * n)
        return n

    return func_inner

f = func_closure()
print(f())
print(f())
print(f())
print("f.__closure__ =", f.__closure__)
print("f.__closure__[0].cell_contents =", f.__closure__[0].cell_contents)
print("f.__closure__[1].cell_contents =", f.__closure__[1].cell_contents)
print(f())
print("f.__closure__[0].cell_contents =", f.__closure__[0].cell_contents)
print("f.__closure__[1].cell_contents =", f.__closure__[1].cell_contents)
【出力例】
1
2
3
f.__closure__ = (<cell at 0x~: list object at 0x~>, <cell at 0x~: list object at 0x~>)
f.__closure__[0].cell_contents = [1, 2, 3]
f.__closure__[1].cell_contents = [1, 4, 9]
4
f.__closure__[0].cell_contents = [1, 2, 3, 4]
f.__closure__[1].cell_contents = [1, 4, 9, 16]

return【関数の戻り値】3.8

メモ  ( 複数の戻り値 複数の戻り値の代入 ) 構文

メモ

構文

return [戻り値 (複数:カンマ区切り)[,]]

戻り値
単一:任意
複数:タプル (tuple【タプル型】 参照)
省略:None
※:末尾のカンマは無視 (空の値等はなし)

def func_0():
    return

def func_1(p1):
    return p1*p1

def func_3(p1):
    return p1, p1*p1, p1*p1*p1


print(func_0())
# 出力:None
print(func_1(2))
# 出力:4

r1 = func_3(2)
print(r1)
# 出力:(2, 4, 8)
(r1, r2, r3) = func_3(2)
print(r1, r2, r3)
# 出力:2 4 8
r1, r2, r3 = func_3(2)
print(r1, r2, r3)
# 出力:2 4 8

#r1, r2 = func_3(2)  # ValueError 例外
#r1, r2, r3, r4 = func_3(2)  # ValueError 例外

r1, *r2 = func_3(2)
print(r1, r2)
# 出力:2 [4, 8]
*r1, r2 = func_3(2)
print(r1, r2)
# 出力:[2, 4] 8
*r1, = func_3(2)
print(r1)
# 出力:[2, 4, 8]
r1, r2, r3, *r4 = func_3(2)
print(r1, r2, r3, r4)
# 出力:2 4 8 []
# アンパック指定
def func_return_3_7():
    lst = [1, 2, 3]
    tpl = (11, 12, 13)
    return (*lst, *tpl)

# Python 3.8
def func_return_3_8():
    lst = [1, 2, 3]
    tpl = (11, 12, 13)
    return *lst, *tpl

x = func_return_3_7()
print(x)
# 出力:(1, 2, 3, 11, 12, 13)

# Python 3.8
x = func_return_3_8()
print(x)
# 出力:(1, 2, 3, 11, 12, 13)

lambda【ラムダ式 (無名関数)】

メモ 構文

メモ

構文

lambda [引数 (複数:カンマ区切り)] : 返却値 (式)

引数def【関数定義】を参照 (但し、アノテーション指定は不可)

l = ["a_D", "A_C", "b_B", "B_A"]
print(l)
# 通常ソート
print(sorted(l))
# 最後の文字順
print(sorted(l, key=lambda s: s[len(s) - 1]))
【出力例】
['a_D', 'A_C', 'b_B', 'B_A']
['A_C', 'B_A', 'a_D', 'b_B']
['B_A', 'b_B', 'A_C', 'a_D']
list1 = [1, 2, 3, 5, 8, 13]
map2 = map(lambda x: "偶数" if (x % 2) == 0 else "奇数", list1)
list2 = list(map2)
for i in range(len(list1)):
    print(list1[i], list2[i])
【出力例】
1 奇数
2 偶数
3 奇数
5 奇数
8 偶数
13 奇数