2009-04-15 3 views
100
나 '파이썬에 뛰어을'및 클래스의 장에서 읽고 있었다

의 재정 __init__은이 예제를 제공합니다상속 및 파이썬

class FileInfo(UserDict): 
    "store file metadata" 
    def __init__(self, filename=None): 
     UserDict.__init__(self) 
     self["name"] = filename 

저자는 말한다 당신은 __init__ 메소드를 오버라이드 (override) 할 경우 올바른 매개 변수를 사용하여 부모 __init__을 명시 적으로 호출해야합니다.

  1. 무슨 FileInfo 클래스는 하나 개 이상의 상위 클래스가 있다면?
    • 모든 조상 클래스의 __init__ 메서드를 명시 적으로 호출해야합니까?
  2. 또한 재정의하려는 다른 방법으로이 작업을 수행해야합니까?
+3

오버로드는 오버라이드와는 다른 개념입니다. –

+2

예, 더 나은 책/튜토리얼을 찾아야합니까? –

답변

129

이 책은 subclass-superclass 호출과 관련하여 약간 날짜가 있습니다. 또한 내장 클래스를 서브 클래스 화하는 데 다소 날짜가 있습니다.

요즘은 이렇게 보입니다.

class FileInfo(dict): 
    """store file metadata""" 
    def __init__(self, filename=None): 
     super(FileInfo, self).__init__() 
     self["name"] = filename 

다음 사항에 유의하십시오.

  1. 우리는 직접 내장 클래스를 하위 클래스는 등 dict, list, tuple,

  2. 것처럼 super 함수는이 클래스의 슈퍼 클래스를 추적 처리하고 적절하게에서 함수를 호출.

+4

을 고쳐 주셔서 감사합니다. –

+1

그래서 다중 상속의 경우, super()가 그들을 대신하여 모두 추적합니까? – Dana

+2

dict .__ init __(), 정확히 무엇입니까? –

3

FileInfo 클래스에 둘 이상의 상위 클래스가있는 경우 모든 __init __() 함수를 반드시 호출해야합니다. 소멸자 인 __del __() 함수에 대해서도 동일한 작업을 수행해야합니다.

2

예, 각 상위 클래스에 대해 __init__으로 전화해야합니다. 두 부모 모두에있는 함수를 재정의하는 경우 함수에 대해서도 마찬가지입니다.

10

당신은 기본 클래스 (들)의 __init__ 메소드를 호출 할이없는 정말로,하지만 당신은 일반적으로 기본 클래스의 나머지 부분에 대한 필요가 몇 가지 중요한 초기화를 할 것이기 때문에 그것을 할을 원한다 클래스 메서드가 작동합니다.

다른 방법은 사용자의 의도에 따라 다릅니다. 기본 클래스 비헤이비어에 무언가를 추가하려는 경우 기본 클래스 메서드를 자신의 코드에 추가로 호출해야합니다. 기본 동작을 변경하려면 기본 클래스의 메서드를 호출하고 파생 클래스에서 직접 모든 기능을 구현할 수 있습니다.

+4

기술적 완성도를 위해 threading.Thread와 같은 일부 클래스는 부모의 __init__ 호출을 피하려고 시도 할 때 거대한 오류를 발생시킵니다. –

+5

"이베이스의 생성자를 호출 할 필요가 없습니다."라는 말은 모두 매우 자극적입니다. 내가 아는 어떤 언어로도 전화 할 필요가 없습니다. 그것들 모두는 회원들을 초기화하지 않음으로써 거의 같은 방식으로 실패 할 것입니다. 기본 클래스를 초기화하지 않을 것을 제안하는 것은 여러 가지면에서 잘못입니다. 클래스에 초기화가 필요하지 않은 경우 나중에 필요합니다. 생성자는 클래스 구조/언어 구문의 인터페이스의 일부이므로 올바르게 사용해야합니다. 파생 된 생성자에서 언젠가 그것을 호출하는 것이 올바른 사용입니다. 그렇게해라. – AndreasT

17

상속해야하는 각 클래스에서 자식 클래스의 시작시 init'd가 필요한 각 클래스의 루프를 실행할 수 있습니다 ... 복사 할 수있는 예제가 더 잘 이해 될 수 있습니다 ...

class Female_Grandparent: 
    def __init__(self): 
     self.grandma_name = 'Grandma' 

class Male_Grandparent: 
    def __init__(self): 
     self.grandpa_name = 'Grandpa' 

class Parent(Female_Grandparent, Male_Grandparent): 
    def __init__(self): 
     Female_Grandparent.__init__(self) 
     Male_Grandparent.__init__(self) 

     self.parent_name = 'Parent Class' 

class Child(Parent): 
    def __init__(self): 
     Parent.__init__(self) 
#---------------------------------------------------------------------------------------# 
     for cls in Parent.__bases__: # This block grabs the classes of the child 
      cls.__init__(self)  # class (which is named 'Parent' in this case), 
            # and iterates through them, initiating each one. 
            # The result is that each parent, of each child, 
            # is automatically handled upon initiation of the 
            # dependent class. WOOT WOOT! :D 
#---------------------------------------------------------------------------------------# 



g = Female_Grandparent() 
print g.grandma_name 

p = Parent() 
print p.grandma_name 

child = Child() 

print child.grandma_name 
+1

'Child .__ init__ '의 for 루프가 필요하지 않은 것처럼 보입니다. 제가 예제에서 그것을 제거하면, 아이는 여전히 "할머니"를 프린트합니다. 조부모 초기화가'Parent' 클래스에 의해 처리되지 않습니까? – Adam

+2

granparents init은 이미 부모의 init에 의해 처리 된 것 같지 않습니까? – johk95