1

別のモジュールで定義された関数を呼び出す一連のクラスを作成しています。どの関数を呼び出す必要があるかを知るために、関数はクラスの変数として格納されます (または、少なくともそれが私が試したことです)。ただし、呼び出そうとすると、関数がクラスメソッドであると自動的に想定され、「self」が引数として渡されます。関数が受け取った引数が多すぎるため、論理的にエラーが発生します。関数がクラスメソッドになるのを避ける方法を知っていますか。

コードは次のようになります。

# Module A
def func1(a):
    print a
def func2(a):
    print a,a

# Module B
from A import *
class Parent:
    def func():
        self.sonFunc("Hiya!")
class Son1:
    sonFunc = func1
class Son2:
    sonFunc = func2

so = Son1()
s.func()
# Should print "Hiya!"
s = Son2()
s.func()
# Should print "Hiya! Hiya!"

ありがとう

4

1 に答える 1

5

あなたがしていることは、やや非標準/奇妙なことですが、これはうまくいくはずです:

class Son_1(object):

    son_func = staticmethod(func_1)

class Son_2(object):

    son_func = staticmethod(func_2)

通常、staticmethodはデコレータとして使用されますが、デコレータは構文糖衣であるため、この方法でも使用できます。

間違いなくクリーンですが、より高度な方法は次のmetaclassとおりです。

class HasSonMeta(type):

    def __new__(cls, name, bases, attrs):

        attrs['son_func'] = staticmethod(attrs.pop('__son_func__'))
        return type.__new__(cls, name, bases, attrs)


class Son1(object):

     __metaclass__ = HasSonMeta
     __son_func__ = func_1

class Son2(object):

    __metaclass__ = HasSonMeta
    __son_func__ = func_2

この形式を使用すると、関数をクラスで直接定義することもできます (ただし、このコードを読む人にとってはさらに混乱します)。

class Son3(object):

    __metaclass__ = HasSonMeta

    def __son_func__():

        pass

これが最適な実装である非常に狭い/あいまいなシナリオが存在する可能性がありますが、関数を基本クラスに配置し、必要に応じて子でそれらを参照 (またはオーバーライド) することで、より適切に機能する可能性があります。

于 2013-03-28T17:13:27.530 に答える