여기서 제가 말하는 것은 중첩 클래스입니다. 기본적으로 모델링중인 두 개의 클래스가 있습니다. DownloadManager 클래스 및 DownloadThread 클래스. 여기서 명백한 OOP 개념은 구성입니다. 그러나 컴포지션이 반드시 중첩을 의미하는 것은 아닙니다.
다음과 같은 코드가 있습니다.
class DownloadThread:
def foo(self):
pass
class DownloadManager():
def __init__(self):
dwld_threads = []
def create_new_thread():
dwld_threads.append(DownloadThread())
하지만 지금은 중첩이 더 나은 상황이 있는지 궁금합니다. 다음과 같은 것 :
class DownloadManager():
class DownloadThread:
def foo(self):
pass
def __init__(self):
dwld_threads = []
def create_new_thread():
dwld_threads.append(DownloadManager.DownloadThread())
답변
“내부”클래스가 일회성이며 외부 클래스 의 정의 외부에서 사용되지 않을 때이 작업을 수행 할 수 있습니다 . 예를 들어 메타 클래스를 사용하려면 때때로 다음을 수행하는 것이 편리합니다.
class Foo(object):
class __metaclass__(type):
....
메타 클래스를 별도로 정의하는 대신 한 번만 사용하는 경우.
이와 같은 중첩 클래스를 사용한 유일한 다른 경우에는 외부 클래스를 네임 스페이스로만 사용하여 밀접하게 관련된 클래스를 그룹화했습니다.
class Group(object):
class cls1(object):
...
class cls2(object):
...
그런 다음 다른 모듈에서 Group을 가져 와서 Group.cls1, Group.cls2 등으로 참조 할 수 있습니다. 그러나 모듈을 사용하여 정확히 동일한 작업을 수행 할 수 있다고 주장 할 수 있습니다 (아마도 덜 혼란스러운 방식으로).
답변
저는 Python을 모르지만 귀하의 질문은 매우 일반적입니다. Python에만 국한된 경우 무시하십시오.
클래스 중첩은 모두 범위에 관한 것입니다. 한 클래스가 다른 클래스의 컨텍스트에서만 의미가 있다고 생각한다면 전자는 아마도 중첩 클래스가되기에 좋은 후보 일 것입니다.
헬퍼 클래스를 개인 중첩 클래스로 만드는 것은 일반적인 패턴입니다.
답변
향상된 기능이 특정 중첩 클래스에 캡슐화 된 상속 된 클래스를 생성하려는 경우 중첩 클래스에 대한 또 다른 사용법이 있습니다.
이 예를 참조하십시오.
class foo:
class bar:
... # functionalities of a specific sub-feature of foo
def __init__(self):
self.a = self.bar()
...
... # other features of foo
class foo2(foo):
class bar(foo.bar):
... # enhanced functionalities for this specific feature
def __init__(self):
foo.__init__(self)
의 생성자 foo
에서 라인 self.a = self.bar()
은 생성되는 foo.bar
객체가 실제로 객체 인 경우 foo
a를 foo2.bar
생성하고 생성중인 객체가 실제로 객체 인 경우 객체를 생성 foo2
합니다.
클래스 bar
가 foo
상속 된 버전 ( bar2
예를 들어 호출 됨)뿐만 아니라 클래스 외부에서 정의 된 경우 새 클래스를 정의하는 foo2
것이 훨씬 더 고통 스러울 foo2
것입니다 self.a = bar2()
. 이는 전체 생성자를 다시 작성하는 것을 의미합니다.
답변
메타 클래스를 처리하는 경우를 제외하고는이 작업을 수행하는 데 아무런 이점이 없습니다.
클래스 : 스위트 룸은 실제로 당신이 생각하는 것과 다릅니다. 이상한 범위이고 이상한 일을합니다. 정말 수업도 안 해요! 클래스 이름,베이스, 속성 사전 및 메타 클래스와 같은 일부 변수를 수집하는 방법 일뿐입니다.
이름, 딕셔너리 및베이스는 모두 메타 클래스 인 함수에 전달 된 다음 class : suite가 있던 범위의 변수 ‘name’에 할당됩니다.
메타 클래스를 엉망으로 만들고 실제로 스톡 표준 클래스 내에 클래스를 중첩하여 얻을 수있는 것은 코드를 읽기 어렵고, 코드를 이해하기 어렵고, 왜 ‘클래스’인지 잘 알지 못하면 이해하기 매우 어려운 이상한 오류입니다. 범위는 다른 파이썬 범위와 완전히 다릅니다.
답변
클래스 생성기로 클래스를 사용할 수 있습니다. 처럼 (커프 코드에서 일부 🙂
class gen(object):
class base_1(object): pass
...
class base_n(object): pass
def __init__(self, ...):
...
def mk_cls(self, ..., type):
'''makes a class based on the type passed in, the current state of
the class, and the other inputs to the method'''
이 기능이 필요할 때 매우 분명해 질 것 같습니다. 비슷한 일을 할 필요가 없다면 좋은 사용 사례가 아닐 것입니다.
답변
아니요, 구성은 중첩을 의미하지 않습니다. 외부 클래스의 네임 스페이스에서 더 숨기려면 중첩 된 클래스를 갖는 것이 좋습니다.
어쨌든, 귀하의 경우 중첩에 대한 실질적인 사용이 보이지 않습니다. 코드를 읽기 (이해) 어렵게 만들며 들여 쓰기를 증가시켜 줄이 더 짧아지고 분할되기 쉽습니다.