복붙노트

[PYTHON] 내부 클래스 : 생성시 외부 클래스 객체를 얻으려면 어떻게해야합니까?

PYTHON

내부 클래스 : 생성시 외부 클래스 객체를 얻으려면 어떻게해야합니까?

다음 Python (2.x 또는 3.x에서 실행)을 고려하십시오.

class Outer(object):
  pass

  class Inner(object):
    def __init__(self):
      print("Inner.self", self)

o = Outer()
i = o.Inner()

Inner .__ init __ () 내부에있는 동안 내 손을 잡고 싶습니다. 그러나:

이걸 어떻게 달성 할 수 있는지 제안 해 주시겠습니까?

지금 당장은 스레드 로컬 저장소를 사용하는 것이 가장 좋습니다. 내 유스 케이스에서는, o.Inner ()를 만들 때마다, 이미 어딘가에있는 메소드 안에있다. 그리고 추가하는 것이별로 중요하지 않다.

threading.local()["my o object"] = o

내 코드에.

이것은 제가 생각하기에 기꺼이 부끄러움의 수준에 대한 아이디어를줍니다.

해결법

  1. ==============================

    1.파이썬 2.6에서는 사용자 정의 설명자인 클래스 장식자가 지정한 스펙과 일치합니다.

    파이썬 2.6에서는 사용자 정의 설명자인 클래스 장식자가 지정한 스펙과 일치합니다.

    class InnerClassDescriptor(object):
      def __init__(self, cls):
        self.cls = cls
      def __get__(self, instance, outerclass):
        class Wrapper(self.cls):
          outer = instance
        Wrapper.__name__ = self.cls.__name__
        return Wrapper
    
    class Outer(object):
      @InnerClassDescriptor
      class Inner(object):
        def __init__(self):
          print self.outer
    
    o = Outer()
    i = o.Inner()
    print 'Outer is a', type(Outer)
    print 'Inner is a', type(o.Inner)
    

    이것은 방출한다 :

    <__main__.Outer object at 0x82f90>
    Outer is a <type 'type'>
    Inner is a <type 'type'>
    

    그걸 확인하기 위해

    당신의 특유의 스펙대로. 물론, 재진입을 위해 매번 다른 클래스가 될 필요가 있습니다 - 단일 스레드 환경에서도 다음과 같습니다.

    o1 = Outer()
    o2 = Outer()
    i1 = o1.Inner
    i2 = o2.Inner
    print i1(), i2(), i1(), i2()
    

    O1.Inner와 o2.Inner가 반환 한 클래스가 아닌 다른 곳에서는 (예 : TLS에서)이 사용에 대해 끔찍한 결과가 발생합니다.

    하지만 "o.Inner는 Outer의 인스턴스 인 가능한 모든 클래스 객체와 동일해야합니다."따라서이 코드는 사용자가 제공 한 스펙을 완전히 충족합니다.

  2. ==============================

    2.메타 클래스를 사용하여 내부 클래스를 외부 클래스에 바인딩하는 __get__ 설명자를 구현할 수 있습니다. 그리고 클래스에 바인딩하는 것에 만 관심이있는 것처럼 보이기 때문에 메서드에 래핑 된 함수와 달리 내부 클래스를 내부에서 수정하는 것이 좋습니다.

    메타 클래스를 사용하여 내부 클래스를 외부 클래스에 바인딩하는 __get__ 설명자를 구현할 수 있습니다. 그리고 클래스에 바인딩하는 것에 만 관심이있는 것처럼 보이기 때문에 메서드에 래핑 된 함수와 달리 내부 클래스를 내부에서 수정하는 것이 좋습니다.

    >>> class Outer(object):
        class Inner(object):
            class __metaclass__(type):
                def __get__(self, instance, owner):
                    self.owner = owner
                    return self
    
    
    >>> Outer.Inner is Outer().Inner
    True
    >>> Outer.Inner.owner is Outer
    True
    

    하위 클래스를 통해 내부 클래스를 래핑하려면 __get__ 본문을 다음으로 대체하십시오.

    return type(self.__name__, (self,), {'owner': owner})
    
  3. ==============================

    3.할 수 없습니다. 그러나 약간의 재 설계로 :

    할 수 없습니다. 그러나 약간의 재 설계로 :

    class Outer(object):
      pass
    
      class _Inner(object):
        def __init__(self, outobj):
          self.outobj = outobj
    
      def Inner(self):
        return self._Inner(self)
    
    o = Outer()
    i = o.Inner()
    
    print o, i.outobj
    
  4. ==============================

    4.내부 클래스를 사용하지 않도록 코드를 다시 디자인하고 외부 또는 내부 인스턴스를 만들 때 명시 적으로 전달하거나 필요하지 않도록 코드를 재 설계해야합니다.

    내부 클래스를 사용하지 않도록 코드를 다시 디자인하고 외부 또는 내부 인스턴스를 만들 때 명시 적으로 전달하거나 필요하지 않도록 코드를 재 설계해야합니다.

  5. ==============================

    5.중첩 된 클래스는 중첩 클래스와 아무런 관련이 없습니다. 그들은 부가 가치도 없다. 중첩 된 클래스를 사용하는 대신 인스턴스의 포함을 사용하십시오. - 외부와 내부를 따로 정의하고, 필요에 따라 외부 또는 외부 인스턴스를 전달할 수있는 내부 .in init__ 인스턴스를 만듭니다. 주장하는 경우 Inner를 Outer의 클래스 속성으로 만들 수 있지만 Outer에 특별한 액세스 권한은 없습니다.

    중첩 된 클래스는 중첩 클래스와 아무런 관련이 없습니다. 그들은 부가 가치도 없다. 중첩 된 클래스를 사용하는 대신 인스턴스의 포함을 사용하십시오. - 외부와 내부를 따로 정의하고, 필요에 따라 외부 또는 외부 인스턴스를 전달할 수있는 내부 .in init__ 인스턴스를 만듭니다. 주장하는 경우 Inner를 Outer의 클래스 속성으로 만들 수 있지만 Outer에 특별한 액세스 권한은 없습니다.

  6. ==============================

    6.파이썬에서 내부 클래스의 외부 클래스 액세스 (https://stackoverflow.com/a/35118717/3787376)를 참조하십시오. 나는 변수, 속성, 함수 및 클래스 (특수 코드 없음) 만 사용하는 간단한 신뢰할 수있는 대답을 제공합니다.

    파이썬에서 내부 클래스의 외부 클래스 액세스 (https://stackoverflow.com/a/35118717/3787376)를 참조하십시오. 나는 변수, 속성, 함수 및 클래스 (특수 코드 없음) 만 사용하는 간단한 신뢰할 수있는 대답을 제공합니다.

  7. from https://stackoverflow.com/questions/2278426/inner-classes-how-can-i-get-the-outer-class-object-at-construction-time by cc-by-sa and MIT license