it-swarm-ko.tech

파이썬에서 다른 클래스 내부에 클래스를 정의하면 이점이 있습니까?

내가 여기서 말하는 것은 중첩 클래스입니다. 기본적으로 모델링하는 두 가지 클래스가 있습니다. 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())
90
fuentesjr

"내부"클래스가 일회성 일 때이 작업을 수행 할 수 있습니다.이 클래스는 외부 클래스의 definition 외부에서 사용되지 않습니다. 예를 들어 메타 클래스를 사용하는 것이 때로는 편리한 경우가 있습니다

class Foo(object):
    class __metaclass__(type):
        .... 

메타 클래스를 한 번만 사용하는 경우 메타 클래스를 별도로 정의하는 대신.

이와 같은 중첩 클래스를 사용한 다른 유일한 시간은 외부 클래스를 네임 스페이스로만 사용하여 밀접하게 관련된 클래스를 그룹화했습니다.

class Group(object):
    class cls1(object):
       ...

    class cls2(object):
       ...

그런 다음 다른 모듈에서 Group을 가져 와서이를 Group.cls1, Group.cls2 등으로 참조 할 수 있습니다. 그러나 모듈을 사용하여 정확히 동일한 (아마 덜 혼동스러운 방식으로) 달성 할 수 있다고 주장 할 수 있습니다.

108
dF.

나는 파이썬을 모른다. 그러나 당신의 질문은 매우 일반적인 것 같습니다. 파이썬에만 해당되는 경우 무시하십시오.

클래스 중첩은 모두 범위에 관한 것입니다. 한 클래스가 다른 클래스의 맥락에서만 의미가 있다고 생각한다면, 클래스는 중첩 클래스가되기에 좋은 후보 일 것입니다.

헬퍼 클래스를 개인, 중첩 클래스로 만드는 일반적인 패턴입니다.

18
André Chalella

메타 클래스를 다루는 경우를 제외하고는 이렇게하면 실제로 이점이 없습니다.

클래스 : 스위트는 실제로 당신이 생각하는 것이 아닙니다. 그것은 이상한 범위이며 이상한 일을합니다. 정말 수업조차하지 않습니다! 클래스의 이름, 기본, 속성의 작은 사전 및 메타 클래스와 같은 일부 변수를 수집하는 방법 일뿐입니다.

이름, 사전 및 기본은 모두 메타 클래스 인 함수에 전달 된 다음 클래스가 suite 인 범위의 변수 'name'에 지정됩니다.

메타 클래스를 엉망으로 만들고 실제로 주식 표준 클래스 내에 클래스를 중첩하여 얻을 수있는 것은 코드를 이해하기 어렵고, 코드를 이해하기 어렵고, 왜 '클래스'인지에 대해 친숙하지 않고 이해하기 어려운 이상한 오류입니다. 범위는 다른 python 범위와 완전히 다릅니다.

6
Jerub

클래스를 클래스 생성기로 사용할 수 있습니다. 같은 (커프 코드에서 일부 :)

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'''

이 기능이 필요할 때 매우 분명합니다. 당신이 그것과 비슷한 것을 할 필요가 없다면 아마도 좋은 유스 케이스가 아닐 것입니다.

5
tim.tadh

향상된 기능이 특정 중첩 클래스에 캡슐화 된 상속 된 클래스를 구성하려는 경우 중첩 클래스의 또 다른 사용법이 있습니다.

이 예를보십시오 :

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의 생성자에서 생성되는 객체가 실제로 foo 객체 인 경우 self.a = self.bar() 행이 foo.bar를 생성하고 생성되는 객체가 실제로 foo2.bar 객체 인 경우 foo2 객체가됩니다.

bar 클래스가 대신 foo 클래스 외부에 정의되고 상속 된 버전 (예 : bar2라고 함) 인 경우 foo2라는 새 클래스를 정의하면 foo2의 구성자가 첫 번째 줄은 self.a = bar2()로 대체되어 전체 생성자를 다시 작성합니다.

4
Thomas

아니요, 구성은 중첩을 의미하지 않습니다. 외부 클래스의 네임 스페이스에서 더 숨기려면 중첩 클래스가있는 것이 좋습니다.

어쨌든, 귀하의 경우 중첩에 실제적인 용도는 없습니다. 코드를 이해하기 어렵게 만들며 (들어가면서) 줄이 짧아지고 분할되기 쉬운 들여 쓰기를 증가시킵니다.

1
Cristian Ciupitu