파이썬에서 다른 클래스 내에서 클래스를 정의하면 이점이 있습니까?
제가 여기서 말하는 것은 중첩된 클래스입니다.기본적으로, 저는 두 개의 수업을 모델링하고 있습니다.Download Manager 클래스 및 다운로드스레드 클래스.여기서 분명한 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에만 해당되면 무시합니다.
클래스 중첩은 범위에 대한 모든 것입니다.한 클래스가 다른 클래스의 맥락에서만 의미가 있다고 생각하면 전자가 내포된 클래스가 되기에 적합한 후보일 수 있습니다.
도우미 클래스를 비공개 중첩 클래스로 만드는 것이 일반적인 패턴입니다.
향상된 기능이 특정 중첩 클래스에 캡슐화된 상속된 클래스를 구성하려는 경우 중첩 클래스에 대한 또 다른 사용법이 있습니다.
다음 예를 참조하십시오.
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
목적어, 그리고 afoo2.bar
생성 중인 객체가 실제로 a일 때 객체foo2
물건.
만약 수업이bar
클래스 외부에서 정의되었습니다.foo
대신, 상속된 버전뿐만 아니라 (이를 호출할 것입니다.bar2
예를 들어, 새 클래스 정의foo2
훨씬 더 고통스러울 것이다, 왜냐하면 건설자는.foo2
번째 을 첫번줄다로대체합야니해다음으을째합으로 대체해야 .self.a = bar2()
전체 생성자를 다시 쓰는 것을 의미합니다.
클래스를 클래스 생성기로 사용할 수 있습니다.좋아요 (일부 오프커프 코드에서는 :)
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'''
이 기능이 필요할 때는 분명하게 알 수 있을 것입니다.이와 유사한 작업을 수행할 필요가 없다면 사용 사례가 좋지 않을 수도 있습니다.
메타 클래스를 취급하는 경우를 제외하고는 이 작업을 수행하는 데 아무런 이점이 없습니다.
클래스: 스위트룸은 정말 당신이 생각하는 것과 다릅니다.그것은 이상한 범위이고, 이상한 일을 합니다.그것은 정말 수업조차 되지 않습니다!클래스 이름, 기본값, 속성 사전 및 메타 클래스와 같은 일부 변수를 수집하는 방법일 뿐입니다.
이름, 사전 및 기본값은 모두 메타 클래스인 함수에 전달된 다음 class: suite가 있었던 범위의 변수 'name'에 할당됩니다.
메타 클래스를 혼란스럽게 하고 실제로 주식 표준 클래스 내에 클래스를 중첩함으로써 얻을 수 있는 것은 코드를 읽기 어렵고 코드를 이해하기 어렵고 '클래스' 범위가 다른 파이썬 범위와 완전히 다른 이유를 잘 알지 못하면 이해하기 어려운 이상한 오류입니다.
이 기능의 좋은 사용 사례는 오류/예외 처리입니다. 예:
class DownloadManager(object):
class DowndloadException(Exception):
pass
def download(self):
...
이제 코드를 읽고 있는 사람은 이 클래스와 관련된 모든 가능한 예외를 알고 있습니다.
클래스 내부 또는 외부에서 정의된 어떤 방식으로든 작동합니다.다음은 도우미 클래스 EmpInit가 클래스 내에 포함된 직원 급여 일정 프로그램입니다. 직원:
class Employee:
def level(self, j):
return j * 5E3
def __init__(self, name, deg, yrs):
self.name = name
self.deg = deg
self.yrs = yrs
self.empInit = Employee.EmpInit(self.deg, self.level)
self.base = Employee.EmpInit(self.deg, self.level).pay
def pay(self):
if self.deg in self.base:
return self.base[self.deg]() + self.level(self.yrs)
print(f"Degree {self.deg} is not in the database {self.base.keys()}")
return 0
class EmpInit:
def __init__(self, deg, level):
self.level = level
self.j = deg
self.pay = {1: self.t1, 2: self.t2, 3: self.t3}
def t1(self): return self.level(1*self.j)
def t2(self): return self.level(2*self.j)
def t3(self): return self.level(3*self.j)
if __name__ == '__main__':
for loop in range(10):
lst = [item for item in input(f"Enter name, degree and years : ").split(' ')]
e1 = Employee(lst[0], int(lst[1]), int(lst[2]))
print(f'Employee {e1.name} with degree {e1.deg} and years {e1.yrs} is making {e1.pay()} dollars')
print("EmpInit deg {0}\nlevel {1}\npay[deg]: {2}".format(e1.empInit.j, e1.empInit.level, e1.base[e1.empInit.j]))
외부에서 정의하려면 EmpInit을 제거하고 EmpInit을 변경합니다.EmpInit()는 일반적인 "has-a" 구성으로 간단히 EmpInit()을 나타냅니다.그러나 Empire가 EmpInit의 컨트롤러이고 사용자가 EmpInit를 직접 인스턴스화하거나 인터페이스하지 않기 때문에 독립 실행형 클래스가 아니기 때문에 EmpInit를 내부에서 정의하는 것이 타당합니다.또한 인스턴스 메서드 수준()은 두 클래스 모두에서 호출되도록 설계되었습니다.따라서 Empinit에 전달할 필요 없이 Empinit에서 정적 메서드로 편리하게 정의할 수 있습니다.수평의
언급URL : https://stackoverflow.com/questions/78799/is-there-a-benefit-to-defining-a-class-inside-another-class-in-python
'programing' 카테고리의 다른 글
스프링 부트 2.5.0 및 잘못된 정의예외: Java 8 날짜/시간 유형 'java.time.Instant'는 기본적으로 지원되지 않습니다. (0) | 2023.07.23 |
---|---|
WHERE를 사용할 수 있는데 왜 외부 키를 사용해야 합니까? (0) | 2023.07.23 |
Spark Dataframe은 중복된 이름을 가진 열을 구분합니다. (0) | 2023.07.23 |
데이터 프레임의 여러 데이터 그룹을 하나의 그림으로 표시하는 방법 (0) | 2023.07.23 |
MySQL에서 지연 함수 시뮬레이션 (0) | 2023.07.23 |