중첩 클래스의 범위?
중첩에서 중첩 클래스의 범위를 이해합니다. 다음은 예제 코드입니다.
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
object-가 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
'IT' 카테고리의 다른 글
C #에서 재진입 잠금 (0) | 2020.07.26 |
---|---|
PhotoPicker 검색 오류 : 오류 도메인 = PlugInKit 코드 = 13 (0) | 2020.07.26 |
불균형 통화의 시작 / 종료 모양 전환 (0) | 2020.07.26 |
C ++에서 참조로 전달되는 동안 매개 변수의 라우팅 (0) | 2020.07.26 |
JSFiddle에서 JavaScript가 작동하지 않는 이유는 무엇입니까? (0) | 2020.07.26 |