programing

중첩된 클래스의 범위?

kingscode 2023. 8. 29. 21:44
반응형

중첩된 클래스의 범위?

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

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에 바인딩된 다음 이 코드는 다음 번에 실행될 때 해당 개체를 사용합니다.)

만약 당신이 모든 것을 원한다면,Inner참조할 대상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

클래스 중첩은 Python에서 다소 드물며 클래스 간의 특별한 관계를 자동으로 의미하지는 않습니다.중첩하지 않는 것이 좋습니다. (클래스 속성을 설정할 수 있습니다.)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

그것은 당신이 명시적으로 해야 하지만, 많은 노력이 필요하지 않습니다.

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

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 Documentation The Python Tutorial에서 찾을 수 있습니다.

번째 오류에 당신의첫실수에대해째번▁for대해▁your에당▁first수.<type 'exceptions.NameError'>: name 'outer_var' is not defined설명은 다음과 같습니다.

메소드 내에서 데이터 속성(또는 다른 메소드!)을 참조하는 간단한 방법은 없습니다.저는 이것이 실제로 방법의 가독성을 높인다는 것을 발견했습니다. 방법을 훑어볼 때 로컬 변수와 인스턴스 변수를 혼동할 가능성이 없습니다.

Python Tutorial 9.4에서 인용.

오류에 당신의두실수에대해째번▁for대해▁your에당▁error.<type 'exceptions.NameError'>: name 'OuterClass' is not defined

클래스 정의가 종료를 통해 정상적으로 유지되면 클래스 개체가 생성됩니다.

파이썬 튜토리얼 9.3.1에서 인용.

그래서 당신이 노력할 때inner_var = Outerclass.outer_var,Quterclass. 아직생않았니다습지성되다않니▁hasn았습▁yet▁that'▁createds. 그것이 이유입니다.name 'OuterClass' is not defined

첫 번째 오류에 대한 자세한 설명은 다음과 같은 지루한 설명:

클래스가 포함 함수의 범위에 액세스할 수 있지만 클래스 내에 중첩된 코드에 대한 포함 범위 역할을 하지 않습니다.Python은 참조된 이름을 찾기 위해 포함 함수를 검색하지만 포함 클래스는 검색하지 않습니다.즉, 클래스는 로컬 범위이며 포함된 로컬 범위에 액세스할 수 있지만 추가 중첩 코드에 대한 포함 로컬 범위 역할을 하지 않습니다.

학문에서 인용한.파이썬(5위).마크 루츠

class c_outer:
    def __init__(self, name:str='default_name'):
        self._name = name
        self._instance_lst = list()
        self._x = self.c_inner()

    def get_name(self):
        return(self._name)

    def add_inner_instance(self,name:str='default'):
        self._instance_lst.append(self.c_inner(name))

    def get_instance_name(self,index:int):
        return(self._instance_lst[index].get_name())


    class c_inner:
        def __init__(self, name:str='default_name'):
            self._name = name
        def get_name(self):
            return(self._name)


outer = c_outer("name_outer")

outer.add_inner_instance("test1")
outer.add_inner_instance("test2")
outer.add_inner_instance("test3")
inner_1 = outer.c_inner("name_inner1")
inner_2 = outer.c_inner("name_inner2")
inner_3 = outer.c_inner("name_inner3")

print(outer.get_instance_name(index=0))
print(outer.get_instance_name(1))
print(outer._instance_lst[2]._name
print(outer.get_name())
print(inner_1.get_name())
print(inner_2.get_name())

test1 test2 test3 name_test1 name_test2 name_test3

언급URL : https://stackoverflow.com/questions/1765677/nested-classes-scope

반응형