151

みたいな状況になってしまって…

class Outer(object):

    def some_method(self):
        # do something

    class Inner(object):
        def __init__(self):
            self.Outer.some_method()    # <-- this is the line in question

OuterクラスからクラスのメソッドにアクセスするにはどうすればよいInnerですか?

4

13 に答える 13

109

内部クラスのインスタンスから、外部のクラス インスタンスにアクセスしようとしています。したがって、 factory-method を使用して Inner インスタンスを構築し、 Outer インスタンスをそれに渡します。

class Outer(object):

    def createInner(self):
        return Outer.Inner(self)

    class Inner(object):
        def __init__(self, outer_instance):
            self.outer_instance = outer_instance
            self.outer_instance.somemethod()

        def inner_method(self):
            self.outer_instance.anothermethod()
于 2011-08-11T23:44:28.647 に答える
92

ネストされたクラスのメソッドは、外部クラスのインスタンス属性に直接アクセスできません。

内部クラスのインスタンスを作成しても、外部クラスのインスタンスが存在するとは限らないことに注意してください。

実際、ネストされたクラスを使用しないことが推奨されることがよくあります。これは、ネストが内部クラスと外部クラスの間の特定の関係を暗示するものではないためです。

于 2010-01-07T23:54:24.477 に答える
37

たぶん私は怒っているかもしれませんが、これは確かに非常に簡単に思えます-問題は、内部クラスを外部クラスのメソッド内に作成することです...

def do_sthg(self):
    ...

def messAround(self):

    outerClassSelf = self

    class Mooble():
        def do_sthg_different(self):
            ...
            outerClassSelf.do_sthg()

さらに...「self」は慣例でのみ使用されるため、次のようにすることができます。

def do_sthg(self):
    ...

def messAround(outerClassSelf):

    class Mooble():
        def do_sthg_different(self):
            ...
            outerClassSelf.do_sthg()

外部クラスの外部からこの内部クラスを作成することはできないと反対されるかもしれません...しかし、これは真実ではありません:

class Bumblebee():

    def do_sthg(self):
        print "sthg"
    
    def giveMeAnInnerClass(outerClassSelf):

        class Mooble():
            def do_sthg_different(self):
                print "something diff\n"
                outerClassSelf.do_sthg()
        return Mooble
    

それから、何マイルも離れたどこかで:

blob = Bumblebee().giveMeAnInnerClass()()
blob.do_sthg_different()    

ボートを少し押し出して、この内部クラスを拡張することもできます (作業を開始するには、 のクラス シグネチャをにsuper()変更する必要があります)。Moobleclass Mooble(object)

class InnerBumblebeeWithAddedBounce(Bumblebee().giveMeAnInnerClass()):
    def bounce(self):
        print "bounce"
    
    def do_sthg_different(self):
        super(InnerBumblebeeWithAddedBounce, self).do_sthg_different()
        print "and more different"
    

ibwab = InnerBumblebeeWithAddedBounce()    
ibwab.bounce()
ibwab.do_sthg_different()

後で

mrh1997 は、この手法を使用して提供される内部クラスの非一般的な継承について興味深い点を提起しました。しかし、解決策は非常に簡単なようです。

class Fatty():
    def do_sthg(self):
        pass
    
    class InnerFatty(object):
        pass
            
    def giveMeAnInnerFattyClass(self):
        class ExtendedInnerFatty(Fatty.InnerFatty):
            pass
        return ExtendedInnerFatty
                
fatty1 = Fatty()
fatty2 = Fatty()

innerFattyClass1 = fatty1.giveMeAnInnerFattyClass()
innerFattyClass2 = fatty2.giveMeAnInnerFattyClass()

print (issubclass(innerFattyClass1, Fatty.InnerFatty))
print (issubclass(innerFattyClass2, Fatty.InnerFatty))
于 2011-08-22T19:38:17.530 に答える
7

私はこれを見つけまし

あなたの質問に合わせて微調整:

class Outer(object):
    def some_method(self):
        # do something

    class _Inner(object):
        def __init__(self, outer):
            outer.some_method()
    def Inner(self):
        return _Inner(self)

どういうわけかこれか何かのデコレータを書くことができると確信しています

関連: python の内部クラスの目的は何ですか?

于 2011-05-16T12:37:35.673 に答える
3

このようにクラスをネストするのではなく、継承を使用するつもりですか? あなたがしていることは、Python ではあまり意味がありません。

Outer内部クラスのメソッド内で参照するだけで の some_method にアクセスできますが、Outer.some_method期待どおりに動作しません。たとえば、これを試してみると:

class Outer(object):

    def some_method(self):
        # do something

    class Inner(object):
        def __init__(self):
            Outer.some_method()

...最初の引数としてインスタンスを受け取ることを期待してInnerいるため、オブジェクトを初期化するときに TypeError が発生します。(上記の例では、基本的に のクラス メソッドとして呼び出そうとしています。)Outer.some_methodOutersome_methodOuter

于 2010-01-08T00:01:25.620 に答える
3

別の可能性:

class _Outer (object):
    # Define your static methods here, e.g.
    @staticmethod
    def subclassRef ():
        return Outer

class Outer (_Outer):
    class Inner (object):
        def outer (self):
            return _Outer

        def doSomething (self):
            outer = self.outer ()
            # Call your static mehthods.
            cls = outer.subclassRef ()
            return cls ()
于 2011-07-29T16:53:47.527 に答える
1

外部メソッドは静的メソッドである可能性があるという@tsnorriの説得力のある考え方を拡張します。

class Outer(object):

    @staticmethod
    def some_static_method(self):
        # do something

    class Inner(object):
        def __init__(self):
            self.some_static_method()    # <-- this will work later

    Inner.some_static_method = some_static_method

問題の行は、実際に呼び出されるまでに機能するはずです。

上記のコードの最後の行は、Inner クラスに、Outer 静的メソッドのクローンである静的メソッドを提供します。


これは Python の 2 つの機能を利用しています。関数は objectであり、スコープは textualです。

通常、ローカル スコープは、(テキスト的に) 現在の関数のローカル名を参照します。

...または私たちの場合は現在のクラスです。そのため、Outer クラス (Innerおよびsome_static_method) の定義に対して「ローカルな」オブジェクトは、その定義内で直接参照できます。

于 2015-10-20T16:57:49.977 に答える
0

クラスを作成して、内部クラスを装飾することができます。この場合、@inner.

これはデコレータであるため: Outer.A = inner(Outer.A)。コードに Outer.A が必要になるとinner.__get__、メソッドが実行され、新しい属性が設定された元のクラス (A) が返されます: A.owner = Outer.

クラス A のクラスメソッド (この場合def add(cls, y=3)は ) は、新しい属性ownerat を使用できますreturn cls.owner.x + y + 1

行,は、クラス inner のインスタンスではないsetattr(owner, name, self.inner)ため、記述子を分割します。owner.name => Outer.A => A

お役に立てれば。

    class inner:
    
        def __init__(self, inner):
            self.inner = inner
    
        def __get__(self, instance, owner):
            print('__get__ method executed, only once... ')
            name = self.inner.__name__
            setattr(self.inner, 'owner', owner) 
            setattr(owner, name, self.inner) # breaks descriptor
            return self.inner #returns Inner
    
    class Outer:
        x = 1
    
        @inner
        class A:
    
            @classmethod
            def add(cls, y=3):
                return cls.owner.x + y + 1
    
    print(Outer.A.add(0)) # First time executes inner.__get__ method
    print(Outer.A.add(0)) # Second time not necessary.

    >> __get__ method executed, only once... 
    >> 2
    >> 2

于 2020-11-26T21:22:31.577 に答える