Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonの関数とオブジェクトメソッド、どちらがより基本的?

Pythonにおける「関数」とは何か

Pythonにおいて、関数とは「呼び出し可能(callable)」なオブジェクトのことです。つまり、呼び出し演算子 () を使って実行できるオブジェクトを指します。ただし、関数だけが呼び出せるわけではありません。__call__ という特殊メソッドを実装すれば、どんなオブジェクトでも関数のように振る舞わせることができます。

関数の定義例

def a():
    pass  # a() は関数の一例

print(a)
print(type(a))

出力結果

<function a at 0x0000000005765C18>
<class 'function'>

メソッドとは ― 関数の特別な姿

メソッドは関数の一種であり、「束縛された(bound)」状態と「束縛されていない(unbound)」状態を持つ点が特徴です。クラスの中で定義された関数がこれに該当します。

コード例

class C:
    def c(self):
        pass

print(C.c)      # クラスから直接参照(旧・非束縛メソッド)
print(type(C.c))
print(C().c)    # インスタンスから参照(束縛メソッド)
print(type(C().c))

出力結果(Python 3)

<function C.c at 0x7f8b1c2d3e50>
<class 'function'>
<bound method C.c of <__main__.C object at 0x7f8b1a4b5c60>>
<class 'method'>

Python 2の時代には、非束縛メソッドをインスタンスを渡さずに呼び出すと、次のようなTypeErrorが発生していました。

Traceback (most recent call last):
  File "~.py", line 11, in <module>
    print C.c()
TypeError: unbound method c() must be called with C instance as first argument (got nothing instead)

なお、Python 3では「非束縛メソッド」という概念自体が撤廃され、クラス属性としてアクセスしたメソッドは単なる関数として扱われます。そのため上記のエラーは起きなくなり、代わりに TypeError: C.c() missing 1 required positional argument: 'self' のような引数不足のエラーが発生します。

束縛メソッドはそのまま関数として使える

Pythonでは、束縛メソッド・通常の関数・__call__ を実装した呼び出し可能オブジェクト・クラスのコンストラクタは、見た目上ほとんど区別がつきません。命名の慣習こそ異なりますが、すべて同じように「呼び出す」ことができます。内部的な実装はまったく違っていても、です。

これは裏を返せば、束縛メソッドをそのまま変数に代入して、関数として使い回せるということです。Pythonが柔軟で強力だと言われる理由の一つがここにあります。

>>> d = A().a   # A() インスタンスの束縛メソッド
>>> d()         # 関数と同じように呼び出せる

len(...) と str(...) の違いは表面には現れない

同じ理屈で、len(...)str(...) にも本質的な違いがあります。後者は型(クラス)のコンストラクタだからです。しかし、オブジェクトの中身を覗いてみない限り、この違いに気づくことはありません。

>>> len
<built-in function len>
>>> str
<class 'str'>

まとめ:より基本的なのは「関数」

結論から言えば、より基本的なのは関数です。メソッドは、関数に特定のインスタンスを結び付けた(束縛した)特別な形にすぎません。さらに言えば、__call__ を実装すればどんなオブジェクトでも関数のように呼び出せます。つまりPythonでは「呼び出し可能(callable)であること」こそがすべての土台となっており、関数・メソッド・クラスの違いは、その土台の上に成り立つ表現方法の違いにすぎないのです。

  1. PythonのLambda関数入門:名前のない匿名関数の基本と使い方

    PythonのLambda関数(ラムダ関数)は、1行で記述できる匿名関数です。リストのフィルタリング、文字列の大文字・小文字変換、数値の掛け算など、名前を必要としない単純な処理にLambda式を活用すると、コードを簡潔に保つことができます。 なぜ関数が必要なのか プログラムの中で同じような処理を何度も実行する場合、コードをその都度書き込むのは非効率です。処理の内容を変更したいとき、同じコードが書かれている箇所をすべて修正しなければならず、コードベースが大きくなるほど修正にかかる手間と時間は膨らみます。 そこで役立つのが関数です。Pythonには、素早く関数を宣言できる特別な種類の関数「匿名関

  2. JavaScriptにおける関数とメソッドの違いとは?わかりやすく解説

    JavaScriptにおいて、関数とメソッドは本質的には同じものです。両者の違いは、メソッドがオブジェクトのプロパティとして定義された関数であるという点にあります。つまり、独立して定義されたものを「関数」、オブジェクトに紐づけられたものを「メソッド」と呼びます。 JavaScriptの関数の基本形 まず、一般的な関数の定義方法を見てみましょう。 function functionname(param1, param2){ // 処理内容 } JavaScriptのメソッドの例 メソッドは、オブジェクトに関連付けられた関数です。次の例では、employeeオブジェクトの中にdetails