IT

중첩 클래스의 범위?

lottoking 2020. 7. 26. 11:51
반응형

중첩 클래스의 범위?


중첩에서 중첩 클래스의 범위를 이해합니다. 다음은 예제 코드입니다.

class OuterClass:
    outer_var = 1
    class InnerClass:
        inner_var = outer_var

클래스 생성이 완료되지 않고 발생합니다.

<type 'exceptions.NameError'>: name 'outer_var' is not defined

시도 inner_var = Outerclass.outer_var가 작동하지 않습니다. 나는 얻다 :

<type 'exceptions.NameError'>: name 'OuterClass' is not defined

나는 정적에 액세스 outer_var하려고 InnerClass.

제출할 수있는 방법이 있습니까?


class Outer(object):
    outer_var = 1

    class Inner(object):
        @property
        def inner_var(self):
            return Outer.outer_var

이것은 다른 언어에서 작동하는 것과 같은 방식으로 사용하는 대신 전역 조회를 사용합니다 outer_var. 이름 Outer이 바인드 된 오브젝트를 변경하면 이 코드는 다음에 실행될 때 해당 오브젝트를 사용합니다.

모든 대신 Innerobject-가 Outer이유에 , 대한 참조를 갖기 를 원한다면 outer_var실제로 인스턴스 속성입니다.

class Outer(object):
    def __init__(self):
        self.outer_var = 1

    def get_inner(self):
        return self.Inner(self)
        # "self.Inner" is because Inner is a class attribute of this class
        # "Outer.Inner" would also work, or move Inner to global scope
        # and then just use "Inner"

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

        @property
        def inner_var(self):
            return self.outer.outer_var

중첩 클래스는 문법에서 흔하지 않는 클래스 사이의 특별한 관계를 자동으로 암시합니다. 중첩하지 않는 것이 좋습니다. 경우 원하는 클래스 속성을 Outer으로 설정할 수 있습니다 Inner.


나는 당신이 할 수 있습니다.

class OuterClass:
    outer_var = 1

    class InnerClass:
        pass
    InnerClass.inner_var = outer_var

문제는 다음과 가변적입니다.

블록은 단위로 실행되는 Python 프로그램 텍스트 조각입니다. 모듈, 함수 본문 및 클래스 정의는 다음과 같습니다.
(...)
범위는 블록 내에서 이름의 가시성을 정의합니다.
(...)
클래스 블록에 정의 된 이름의 범위는 클래스 블록으로 제한됩니다. 메소드의 코드 블록으로 확장되지 않습니다. 여기에 포함되는 함수 범위를 사용하여 구현합니다. 이것은 다음이 실패 함을 의미합니다.

   class A:  

       a = 42  

       b = list(a + i for i in range(10))

http://docs.python.org/reference/executionmodel.html#naming-and-binding

위의 의미 :
함수 본문은 코드 블록이고 메서드는 함수이므로 클래스 정의에있는 함수 본문에서 정의 된 이름은 함수 본문으로 확장되지 않습니다.

귀하의 경우에 이것을 의역 :
클래스 정의는 코드 블록이며 외부 클래스 정의에 존재하는 내부 클래스 정의에서 정의 된 이름은 내부 클래스 정의로 확장되지 않습니다.


중첩 클래스를 사용하지 않는 것이 더 나을 수 있습니다. 중첩해야하는 경우 다음을 시도하십시오.

x = 1
class OuterClass:
    outer_var = x
    class InnerClass:
        inner_var = x

또는 중첩하기 전에 두 클래스를 모두 선언하십시오.

class OuterClass:
    outer_var = 1

class InnerClass:
    inner_var = OuterClass.outer_var

OuterClass.InnerClass = InnerClass

(그 후에 del InnerClass필요한 경우 할 수 있습니다 .)


가장 쉬운 솔루션 :

class OuterClass:
    outer_var = 1
    class InnerClass:
        def __init__(self):
            self.inner_var = OuterClass.outer_var

명시 적이어야하지만 많은 노력이 필요하지 않습니다.


파이썬에서 변경 가능한 객체는 참조로 전달되므로 외부 클래스의 참조를 내부 클래스에 전달할 수 있습니다.

class OuterClass:
    def __init__(self):
        self.outer_var = 1
        self.inner_class = OuterClass.InnerClass(self)
        print('Inner variable in OuterClass = %d' % self.inner_class.inner_var)

    class InnerClass:
        def __init__(self, outer_class):
            self.outer_class = outer_class
            self.inner_var = 2
            print('Outer variable in InnerClass = %d' % self.outer_class.outer_var)

모든 설명은 Python 문서 The Python Tutorial 에서 찾을 수 있습니다.

첫 번째 오류 <type 'exceptions.NameError'>: name 'outer_var' is not defined. 설명은 다음과 같습니다.

메서드 내에서 데이터 속성 (또는 다른 메서드!)을 참조하기위한 속기는 없습니다. 이것은 실제로 메서드의 가독성을 증가 시킨다는 것을 발견했습니다. 메서드를 살펴볼 때 지역 변수와 인스턴스 변수를 혼동 할 가능성이 없습니다.

Python Tutorial 9.4 에서 인용

두 번째 오류 <type 'exceptions.NameError'>: name 'OuterClass' is not defined

클래스 정의가 정상적으로 남으면 (끝까지) 클래스 객체가 생성됩니다.

Python Tutorial 9.3.1 에서 인용

당신이하려고하면 그래서 inner_var = Outerclass.outer_var는이 Quterclass이유가 아직 생성되지 않은name 'OuterClass' is not defined

첫 번째 오류에 대한 더 자세하지만 지루한 설명 :

비록 클래스가 둘러싸는 함수의 범위에 접근 할 수 있지만, 그것들은 클래스 내에 중첩 된 코드에 대한 둘러싸는 범위의 역할을하지 않습니다. 파이썬은 참조 된 이름에 대해 둘러싸는 함수를 검색하지만 둘러싸는 클래스는 검색하지 않습니다. 즉, 클래스는 로컬 범위이고 둘러싸는 로컬 범위에 액세스 할 수 있지만 추가 중첩 코드에 대한 둘러싸는 로컬 범위 역할을하지 않습니다.

Learning.Python (5th) .Mark.Lutz 에서 인용

참고 URL : https://stackoverflow.com/questions/1765677/nested-classes-scope

반응형