1

私はそこにたくさんの同様の質問があることを知っています。しかし、私の質問は異なります。 オーバーライドできないメソッドを作りたくありません。 新しく作成したクラスを保護して、誤って何かを上書きしないようにします。

プレフィックスとしてアンダースコアを使用するのはかなり良いですが、すぐに多くのアンダースコアを持つ多くのメソッドを取得します。継承されたクラスのどこかで、祖先のクラスメソッドをオーバーライドします。

私が本当に欲しいのは、これと同じくらい単純なものです。

class Cat(Mammal):
    def walk(self):
        if ancestor_has_function('walk'):
            parent.walk();
        do_something_here();

Catの祖先(哺乳類、動物、またはLifeFormのいずれか)のいずれかに「歩行」メソッドがある場合は、最初に親メソッドを実行する必要があります。

Pythonでこれを行う可能性はありますか?

編集: 例えば、これは私が良いと思った答えの履歴書です。これが他の人に役立つことを願っています:

class Animal(object):
    pass
    #def walk(self):
    #    print('animal walk')

class Mammal(Animal):
    def walk(self):
        if hasattr(super(Mammal, self), 'walk') and callable(super(Mammal,self).walk):
            super(Mammal, self).walk()
        print('mammal walk')

class Cat(Mammal):
    def walk(self):
        super(Cat, self).walk()
        print('cat walk')
    
if __name__ == '__main__':
    cat = Cat()
    cat.walk()

そしてここに出力があります:

哺乳類の散歩

キャットウォーク

動物の歩行方法のコメントを外してみてください。そうすれば、それも機能するようになります。

4

5 に答える 5

6

一般的に言えば、スーパークラスが最も一般的なもので、少なくともスタブメソッドを提供することをお勧めします。

class Mammal(object):
    def walk(self):
        pass

super()次に、 :を呼び出してサブクラスに拡張します。

class Cat(Mammal):
    def walk(self):
        super(Cat, self).walk()  # or just super().walk(), in Python 3+
        do_something_here()

呼び出しsuper()を条件付きにするのは難しいことではありませんが、それはおそらく悪い考えです。それは冗長で壊れやすく、悪い習慣を助長するだけです。本当に、本当にそれを行う正当な理由がある場合は、他のオブジェクトと同じようhasattr()に、オブジェクトで使用できます。super

class Cat(Mammal):
    def walk(self):
        if hasattr(super(Cat, self), 'walk'):
            super(Cat, self).walk()
        do_something_here()

ただし、何らかの理由で特定のメソッドが存在することに依存できないサードパーティライブラリのクラスをサブクラス化するなど、通常とは異なる状況でのみこれを実行する必要があります。

于 2012-09-06T10:45:44.363 に答える
3

うん。hasattr特定の名前の属性があるかどうかを確認します。callable特定の属性が呼び出し可能かどうかを確認します。

class Mammal(object):
    def walk(self):
        print "walking"


class Cat(Mammal):
    def walk(self):
        if hasattr(Mammal,'walk') and callable(Mammal.walk):
            Mammal.walk(self);
        print "another walking!"

そして今:

>>> my_cat = Cat()
>>> my_cat.walk()
walking
another walking!

super次のように親クラスを取得するためにも使用できることに注意してください。

if hasattr(super(Cat, self),'walk'):
于 2012-09-06T10:43:50.690 に答える
1

この関数を使用してdir()、モジュールまたはクラスに対して宣言されているすべての名前を取得できます。階層の上位のクラスで宣言されたメソッドも含まれます。ただし、これには属性も含まれるため、callable()最初に確認してください。

また、親メソッドの呼び出しはPythonでは少し異なって見えます。以下のコードを参照してください。

def walk(self):
    if "walk" in dir(Mammal) and callable(Mammal.walk):
        Mammal.walk(self)
    # do something
于 2012-09-06T10:41:21.370 に答える
0

元のメソッドをフィールドに保持できます

class MyClass:
    def __method(self):
        pass

    def __init__(self):
        self.method = __method

IDを確認して、保存されたメソッドを呼び出すよりも

于 2012-09-06T10:37:52.213 に答える
0
import inspect

class SomeClass():
    def __init__(self):
        ...

    def somefunc(self):
        ....

    def someOtherFunc(self):
        ....


allmembers = inspect.getmembers(SomeClass, predicate=inspect.ismethod)

getmembers指定されたクラス内で定義されているすべてのメソッドのリストを返します。これは、メソッド名と定義を含むタプルのリストです。

[('__init__', <unbound method SomeClass.__init__>),
 ('somefunc', <unbound method SomeClass.somefunc>),
 ('someOtherFunc', <unbound method SomeClass.someOtherFunc>)]

タプルの最初の要素は文字列であるため、文字列ベースのメソッドを使用して、次のような基本メソッドをフィルタリングできます。__init__

allmembers = filter(lambda x: not x.startswith('__'), [x[0] for x in inspect.getmembers(SomeClass, predicate=inspect.ismethod))])

[('somefunc', <unbound method SomeClass.somefunc>),
('someOtherFunc', <unbound method SomeClass.someOtherFunc>)]

クラス内で定義されているすべてのメソッドのリストを取得し、同様の名前のメソッドがあるかどうかを確認できますgetmembers。バインドされていないメソッドインスタンスが返されるため、その関数に簡単にアクセスすることもできます。

于 2012-09-06T10:57:30.487 に答える