web-dev-qa-db-ja.com

クラス定義外でメソッドを定義しますか?

_class MyClass:
    def myFunc(self):
        pass
_

MyFunc()をクラス定義の外部に、おそらく別のモジュール内にも作成できますか?

43
user975135

はい。クラスの外部で関数を定義し、それをメソッドとしてクラス本体で使用できます。

def func(self):
    print("func")

class MyClass:
    myMethod = func

定義されたクラスに関数を追加することもできます。

class MyClass:
    pass

def func(self):
    print("func")

MyClass.myMethod = func

必要に応じて異なるモジュールで関数とクラスを定義できますが、あるモジュールでクラスを定義してから別のモジュールでインポートし、動的にメソッドを追加することをお勧めします(2番目の例のように) dは、別のモジュールがインポートされたかどうかに応じて、クラスとは驚くほど異なる動作をします。

これはPythonでは可能ですが、少し珍しいことです。あなたはコメントで「ユーザーはさらに追加することを許可されている」メソッドに言及しています。それは奇妙に聞こえます。ライブラリを作成している場合、おそらくライブラリのユーザーがライブラリ内のクラスにメソッドを動的に追加することを望まないでしょう。ライブラリのユーザーは、クラスを直接変更するよりも、クラスを継承する独自のサブクラスを作成する方が一般的です。

72
Weeble

これが役立つかどうかはわかりませんが、これにより私にとっては少し明確になりました。この方法でこれを行うのがこれまでの良い習慣かどうかはわかりませんが...

class MyClass1(object):
    def __init__(self, bar):
        self.foo = 'updog'
        MyClass1.foobar = bar

class MyClass2(object):
    def __init__(self, bar):
        self.foo = 'updog'
        self.foobar = bar

def bar(self):
    return "What's " + self.foo

最初にMyClass1で何が起こっているのか見てみましょう。このクラスのfoobarは、クラス定義内で定義されたかのように通常のメソッドに似ています(つまり、このクラスのインスタンスにバインドされたメソッドです)。これがどのように見えるか見てみましょう...

In [2]: x = MyClass1(bar)

In [3]: x.foobar
Out[3]: <bound method MyClass1.bar of <__main__.MyClass1 object at 0x104346990>>

In [4]: x.foobar()
Out[4]: "What's updog"

これはMyClass2とどう違うのですか? MyClass2では、foobarは単にbar関数への参照であり、バインドされたメソッドではありません。このため、この関数が適切に機能するにはインスタンスを渡す必要があります。例えば.

In [5]: y = MyClass2(bar)

In [6]: y.foobar
Out[6]: <function __main__.bar>

In [7]: y.foobar()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-6feb04878e5f> in <module>()
----> 1 y.foobar()

TypeError: bar() takes exactly 1 argument (0 given)

In [8]: y.foobar(y)
Out[8]: "What's updog"

それが泥のように明確になることを願っています...

6
ewellinger

はい、クラス外の関数を確実に使用できます。ここに小さな例があります...

def date_parse(date_string):
  return date(date_string)


class MyClass:
   def myFunc(self):
       pass

   def myDateFunc(self, date_string):
      self.date = date_parse(date_string)
1
Matt Alcock

1つのクラスHelperが特殊なクラス(MyClass)に関数を提供する、あなたが探しているものを撮影します。

class Helper(object):

    def add(self, a, b):
        return a + b

    def mul(self, a, b):
        return a * b


class MyClass(Helper):

    def __init__(self):
        Helper.__init__(self)
        print self.add(1, 1)


if __== '__main__':
    obj = MyClass()

これは印刷されます

>>> 2
0
aweis