Python 생성자 및 __init__


107

생성자를 실제로 "생성자"라고 부르는 이유는 무엇입니까? 그들의 목적은 무엇이며 클래스의 메서드와 어떻게 다릅니 까?

또한 __init__한 클래스에 더 많은 것이있을 수 있습니까? 나는 다음을 시도했는데 누군가 결과를 설명해 주시겠습니까?

>>> class test:
    def __init__(self):
        print "init 1"
    def __init__(self):
        print "init 2"

>>> s=test()
init 2

마지막으로 __init__운영자 오버 로더입니까?


41
기술적으로 __init__이니셜 라이저 입니다. 파이썬 생성자__new__. 파이썬은 자동 2 단계 초기화를 사용합니다- __new__유효하지만 (보통) 채워지지 않은 객체 ( bool반대 예제 참조)를 반환 한 다음 __init__자동으로 호출합니다. 이렇게하면 C ++와 같은 언어가 부분적으로 생성 된 객체와 관련된 문제를 피할 수 있습니다. Python에는 객체가 하나도 없습니다 (부분적으로 초기화 될 수 있음). 클래스 __new____init__클래스 모두를 재정의 할 필요가 거의 없습니다 .
Tim Delaney 2012 년

2
@TimDelaney : C ++에서 부분적으로 구성된 객체의 의미를 잘 모르겠습니다.
Sebastian Mach

11
@phresnel C ++에서 객체의 유형은 기본 클래스 생성자에있는 동안 기본 클래스 (하위 클래스가 아님)입니다. 기본 클래스 생성자에서 가상 메서드를 호출 할 수 없으며 하위 클래스가 구현을 제공하도록 할 수 없습니다. Java에서는 기본 클래스 생성자에서 하위 클래스 메서드를 호출 할 수 있지만 하위 클래스 멤버 변수는 기본 클래스 생성자 (및 메서드 호출) 후에 자동으로 초기화됩니다 . Python과 같은 2 단계 초기화를 사용하는 언어에서는 기본 클래스 이니셜 라이저의 메서드를 즐겁게 호출하고 하위 클래스가 동작을 제공 (또는 재정의)하도록 할 수 있습니다.
Tim Delaney 2014

@TimDelaney : 아, 명확히 해주셔서 감사합니다.
Sebastian Mach

4
@TimDelaney. 귀하의 의견이 수락 된 답변을 대체해야한다고 생각합니다.
플라멩코 2011

답변:


114

Python에는 함수 오버로딩이 없습니다. 즉, 이름은 같지만 인수가 다른 여러 함수를 가질 수 없습니다.

코드 예제에서, 당신은하지 않을 과부하 __init__() . 두 번째 정의 가 이름 을 새 메소드에 리 바인드__init__ 하여 첫 번째 메소드에 액세스 할 수 없게 만드는 경우가 발생합니다 .

생성자에 대한 일반적인 질문에 관해서 는 Wikipedia 가 좋은 출발점입니다. Python 관련 항목의 경우 Python 문서를 적극 권장합니다 .


또한 소스 파일이 순차적으로 구문 분석 (해석?)된다는 의미입니까? 나중에 정의한 함수가 이전에 동일한 이름으로 정의 된 함수를 덮어 쓰는지 확인할 수 있습니까? :( 내 Q 사운드는 바보 .. 그것을 알았어 야
0xc0de

4
@ 0xc0de : Python에서 함수 정의는 실제로 실행 가능한 문 이며 위에서 아래로 실행됩니다.
NPE

1
@ 0xc0de 실제로 일어나는 일은 클래스의 본문이 자체 네임 스페이스에서 실행되고 그 네임 스페이스가 메타 클래스 (이름 및베이스 포함)로 전달된다는 것입니다. 함수 정의는 지정된 본문으로 함수를 만들고 이름에 할당합니다. 마지막 과제 __init__는 수업에서 끝나는 것입니다.
skyking 2015

64

생성자를 실제로 "생성자"라고 부르는 이유는 무엇입니까?

생성자 (이름 __new__)는 클래스의 새 인스턴스를 만들고 반환합니다. 따라서 C.__new__클래스 메서드는 클래스 C 의 생성자 입니다.

C.__init__만든 후 인스턴스 메소드는 호출자에게 다시 전달되기 전에를 초기화하기 위해, 특정 인스턴스라고합니다. 따라서이 메서드는 C의 새 인스턴스에 대한 이니셜 라이저 입니다.

클래스의 메서드와 어떻게 다릅니 까?

에 명시된 바와 같이 공식 문서 __init__ 입니다 인스턴스가 생성 된 후라고합니다 . 다른 방법은이 치료를받지 않습니다.

그들의 목적은 무엇입니까?

생성자의 목적은 C.__new__C인스턴스를 생성하는 동안 사용자 지정 동작을 정의하는 것 입니다.

이니셜 라이저의 목적 은 생성 된 후의 C.__init__각 인스턴스에 대한 사용자 지정 초기화를 정의 C하는 것입니다.

예를 들어 Python을 사용하면 다음을 수행 할 수 있습니다.

class Test(object):
    pass

t = Test()

t.x = 10   # here you're building your object t
print t.x

그러나의 모든 인스턴스 가 10과 같은 Test속성을 갖도록하려면 x해당 코드를 내부에 넣을 수 있습니다 __init__.

class Test(object):
    def __init__(self):
        self.x = 10

t = Test()
print t.x

모든 인스턴스 메서드 (클래스의 특정 인스턴스에서 호출되는 메서드)는 인스턴스를 첫 번째 인수로받습니다. 그 인수는 일반적으로 self.

constructor와 같은 클래스 메서드는 __new__대신 클래스를 첫 번째 인수로받습니다.

이제 x속성에 대한 사용자 지정 값을 원한다면 해당 값을 인수로 전달하면됩니다 __init__.

class Test(object):
    def __init__(self, x):
        self.x = x

t = Test(10)
print t.x
z = Test(20)
print t.x

나는 이것이 당신이 의심을 제거하는 데 도움이되기를 바랍니다. 그리고 당신은 이미 다른 질문에 대한 좋은 답변을 받았기 때문에 여기서 멈추겠습니다 :)


9

클래스는 단순히 객체를 생성하는 청사진입니다. 생성자는 개체를 만들 때마다 실행되는 일부 코드입니다. 따라서 두 개의 생성자를 갖는 것은 의미가 없습니다. 일어나는 일은 두 번째 오버가 첫 번째를 쓰는 것입니다.

일반적으로 사용하는 것은 다음과 같이 해당 개체에 대한 변수를 만드는 것입니다.

>>> class testing:
...     def __init__(self, init_value):
...         self.some_value = init_value

따라서 다음과 같이이 클래스에서 객체를 생성 할 수 있습니다.

>>> testobject = testing(5)

그러면 testobject some_value에는이 샘플에서 5 가되는 객체 가 있습니다.

>>> testobject.some_value
5

하지만 샘플에서했던 것처럼 각 개체에 대한 값을 설정할 필요가 없습니다. 다음과 같이 할 수도 있습니다.

>>> class testing:
...     def __init__(self):
...         self.some_value = 5

그러면 some_value의 값은 5가되며 개체를 만들 때 설정할 필요가 없습니다.

>>> testobject = testing()
>>> testobject.some_value
5

내 샘플의 >>> 및 ...는 당신이 작성한 것이 아닙니다. pyshell에서 어떻게 보일지 ...


문제 없습니다, 다행 그것은 : 당신에게 도움이되지
니클라스 닐슨에게

1

coonstructor는 새 개체를 만들 때 자동으로 호출되어 개체를 "구성"합니다. 하나 이상의 init를 가질 수있는 이유 는 이름이 파이썬의 참조 일 뿐이며, 원할 때마다 각 변수가 참조하는 것을 변경할 수 있기 때문입니다 (따라서 동적 타이핑).

def func(): #now func refers to an empty funcion
    pass
...
func=5      #now func refers to the number 5
def func():
    print "something"    #now func refers to a different function

클래스 정의에서 나중에


0

Python에는 메서드 오버로딩 개념이 없습니다. 그러나 선택적 및 키워드 인수를 지정하여 유사한 효과를 얻을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.