月別アーカイブ: 2025年3月

関数の返り値のデフォルト

関数定義の中にreturn が無い場合には、何が返るの?何も返らないの?

Python では、関数内に return が一度も書かれていない場合や、return 文があっても何も返す値が指定されていない場合(例: return だけ書かれている)の場合、関数の呼び出し結果は None になります。

def no_return_function():
    pass

result = no_return_function()
print(result)  # → None と表示される

このように、Python では明示的に値を返さない関数の返り値は None となります。

Python の関数定義の作法:省略可能な引数、デフォルト引数

pythonの関数定義を見ていたら、

def 関数(引数1, 引数2=デフォルト値):

といった書き方がありました。この関数を呼び出すときには、

関数(引数1, 引数2)

のようにして呼び出していました。これってどういうこと?と思ったのですが、関数定義で引数2=デフォルト値 とある場合は、もし引数2が省略されて関数が呼び出された場合には、引数2にはデフォルトとして、そこで指定した値が入るということのようです。

関数 (def) の内部にさらに別の 関数 (def) を定義する「ネストされた関数」について

Python では、関数 (def) の内部に、さらに別の 関数 (def) を定義する(いわゆる「ネストされた関数」)ことが可能です。以下のような理由や効果があります。

  1. スコープを限定し、外部からの利用を防ぐ

    • その関数でしか使わないヘルパー関数を、わざわざモジュールのトップレベル(外部からも呼び出せる範囲)に定義したくない場合、ネストしておくことで“隠蔽”できます。

    • ネスト先の内部関数は、外側の関数を呼び出すときにのみ利用する「ローカルなサブ機能」という役割になります。

  2. 外側の関数のローカル変数を参照できる

    • ネストされた関数は、外側の関数のローカルな変数を読み取り可能です(いわゆるクロージャの仕組み)。

    • たとえば、外側の変数や設定値を、ネスト先で直接参照したいときに便利です。

  3. コードの可読性や整理

    • 大きな処理のかたまり(外側の関数)の中でだけ必要な小機能(内部の関数)をまとめておくと、関連するコードがまとまって見やすいというメリットがあります。

例:

def outer_function(param):
    # outer_function で使うローカル変数
    config_value = 100
    
    def helper_function(x):
        # outer_function のローカル変数 config_value を参照できる
        return x + config_value
    
    # outer_function のメイン処理
    result = []
    for i in range(param):
        result.append(helper_function(i))
    return result

print(outer_function(5))

上記では、helper_functionouter_function の中でしか使わないため、外に出す必要がありません。また config_value に直接アクセスできるので、引数として渡す手間も省けます。

注意点

  • ネストされた関数を外から呼び出す必要がある場合や、多くの箇所で再利用したい場合は、トップレベルに定義したほうが保守性は高いです。

  • ネストし過ぎると却ってコードが分かりにくくなるので、分割のバランスが大事です。

結論:
defの内部にさらにdefを作っている」のは、“その外側の関数だけで使うヘルパーをまとめておきたい”・“外側の関数のローカル変数を参照したい”などの理由で行われます。これは Python で許可されている普通の書き方(ネストされた関数)で、コードの整理やスコープ制御に役立ちます。

(分析:ChatGPT o1)

openpyxl を使って Excel シートを行単位で走査する for row_idx, row in enumerate(sheet.iter_rows(values_only=False)):

この構文は、openpyxl を使って Excel シートを行単位で走査するときの典型的な書き方です。

  • sheet.iter_rows(...) は、指定したシート内の全行を「イテレータ」として返します。

  • enumerate(...) を使うことで、row_idx行番号(0始まり)を格納しつつ、row として実際の行データを取り出すことができます。

  • 引数の values_only=False を指定すると、

    • 取り出されるのは**Cell オブジェクト**のタプルになります。

    • もし values_only=True にすると、セルの実際の値(文字列や数値など)のみが返されることになります。

たとえば values_only=False で書いておけば、次のようなアクセスが可能になります。

for row_idx, row in enumerate(sheet.iter_rows(values_only=False)):
    # row は Cell オブジェクトのタプル
    for cell in row:
        # セルの値: cell.value
        # セルの座標: cell.coordinate
        # セルの背景色、フォントなどの書式情報にもアクセス可能
        pass

一方、単純にセルの中身だけを欲しいときは values_only=True とすることが多いです。すると row は「セルの値のタプル」になり、シンプルに

for row_idx, row_values in enumerate(sheet.iter_rows(values_only=True)):
    # row_values は (値1, 値2, 値3, ...) のタプル
    # 書式情報や座標等は参照できない
    pass

のように書けます。

まとめ:

  • enumerate(sheet.iter_rows(values_only=False))

    • row_idx: 行のインデックス(0から始まるカウント)

    • row: ある行のすべての Cell オブジェクト を格納したタプル

  • values_only の指定

    • False ⇒ セルのオブジェクト(Cell)が欲しい場合

    • True ⇒ セルの中身の値のみを簡単に取得したい場合

用途に応じて切り替えて使ってください。

(文責:ChatGPT o1)