파이썬에서 __init__과 self는 무엇을합니까?


791

저는 파이썬 프로그래밍 언어를 배우고 있으며 완전히 이해하지 못하는 것을 발견했습니다.

같은 방법으로 :

def method(self, blah):
    def __init__(?):
        ....
    ....

무엇을 self합니까? 그것은 무엇을 의미합니까? 필수입니까?

뭐라고를 않는 __init__방법은 무엇입니까? 왜 필요한가요? (기타.)

나는 그들이 OOP 구조 일지 모른다고 생각하지만, 많이 모른다.

답변:


584

이 코드에서 :

class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print self.x + ' ' + foo

... self변수는 객체 자체의 인스턴스를 나타냅니다. 대부분의 객체 지향 언어는이를 객체에 정의 된 메소드에 숨겨진 매개 변수로 전달합니다. 파이썬은 그렇지 않습니다. 명시 적으로 선언해야합니다. A클래스 의 인스턴스를 생성 하고 메소드를 호출 하면 다음 과 같이 자동으로 전달됩니다.

a = A()               # We do not pass any argument to the __init__ method
a.method_a('Sailor!') # We only pass a single argument

__init__방법은 대략 파이썬에서 생성자를 나타내는 것입니다. A()파이썬 을 호출 하면 객체가 생성되어 __init__메서드에 첫 번째 매개 변수로 전달됩니다 . 추가 매개 변수 (예 A(24, 'Hello'):)도 인수로 전달됩니다.이 경우 생성자가 예상하지 않기 때문에 예외가 발생합니다.


8
initx = 'Hello' 외부에 있지만 클래스 안에 넣는 경우 어떻게해야 합니까? 동일한 Java 위치입니까, 아니면 한 번만 초기화되는 정적 변수처럼됩니까?
Jayen April

15
정적 변수와 같습니다. 그것은 한 번만 초기화, 그리고 그것은 가능한 통해의 A.xa.x. 참고 특정 클래스에 재정의하는 것은 기본에 영향을 미치지 않습니다 것을, 그래서 A.x = 'foo'; a.x = 'bar'; print a.x; print A.x인쇄됩니다 bar다음foo
크리스 B.

155
첫 번째 인수가 반드시 호출 될 필요는 없으며 self단지 규칙에 의한 것임을 지적 할 가치가 있습니다 .
Henry Gomersall 2016 년

13
object클래스 선언 의 요점은 무엇입니까 ? 나는 일부 수업에이 수업이 있고 그렇지 않은 수업이 있음을 알았습니다
Chris

9
@Chris Python 2 호환성을위한 것입니다. Python 3에서는 object기본적으로 발생하므로 명시 적으로 상속 할 필요가 없습니다 .
Gabriel

241

네, 맞습니다. 이것들은 oop 구문입니다.

__init__클래스의 생성자입니다. 이 self매개 변수는 개체의 인스턴스를 나타냅니다 ( thisC ++ 에서처럼 ).

class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y

__init__객체에 대한 메모리가 할당 될 때 불려갑니다 :

x = Point(1,2)

self객체와 함께 값을 유지하려면 객체의 메소드 내부 에서 매개 변수 를 사용하는 것이 중요 합니다. 예를 들어 다음 __init__과 같은 방법 을 구현하면

class Point:
    def __init__(self, x, y):
        _x = x
        _y = y

xy매개 변수는 스택 변수에 저장 될 것이고, init 메소드가 범위를 벗어나면 폐기 될 것이다. 로 그 변수를 설정 self._x하고 self._y의 구성원으로 그 변수를 설정 Point오브젝트 (객체의 수명에 대한 접근).


1
그렇다면 self생성자가되고 싶지 않은 이유가 있습니까? 왜 그것을 지정해야합니까? 암시 적이라면 더 좋지 않습니까?
Aaron Franke

내가 아는 한, __ init __은 생성자가 아니며, 개체를 만들 때 실행될 첫 번째 방법이며 __ init __은 개체를 설정하는 데 사용됩니다. __ new __은 파이썬의 생성자입니다.
디 판슈

206

간단한 예

희망이 조금 도움이되기를 바랍니다. 클래스 내부에 선언 된 변수와 __init__함수 내부에 선언 된 변수의 차이점을 이해하는 데 사용한 간단한 예는 다음과 같습니다.

class MyClass(object):
    i = 123
    def __init__(self):
        self.i = 345

a = MyClass()
print(a.i)
print(MyClass.i)

산출:

345
123

7
흥미로운 관찰이지만 나는 당신이 잘못된 길을 가고 있다고 생각합니다. print MyClass.i를 사용하면 '정적'variablie i를 호출하는 것처럼 보입니다. ai와 마찬가지로 멤버 변수를 호출하는 경우 i. 나에게 보인다 초기화는 당신이 클래스의 객체를 생성 할 때 먼저 실행되기 바로 생성자입니다.
captainspi

34
이 예제를 사용하여 '나 자신에게 설명'하려고했던 것입니다. 설정 한 변수는 이름이 같은 클래스 자체의 '정적'변수가 아니라 클래스의 인스턴스__init__전달되는 것입니다.
Dave Everitt

44

한마디로 :

  1. self그것이 제안했듯이, 그 자체를 참조하십시오 -메소드를 호출 한 객체. 즉, 메소드를 호출하는 N 개의 오브젝트가있는 경우 self.a각 N 개의 오브젝트에 대해 별도의 변수 인스턴스를 참조합니다. a각 객체 에 대한 변수의 N 사본을 상상해보십시오
  2. __init__C ++ / Java와 같은 다른 OOP 언어에서 생성자로 불립니다. 기본 아이디어는 해당 클래스의 객체가 생성 될 때 자동으로 호출되는 특수 메소드라는 것입니다

29

__init__생성자처럼 작동합니다. 비 정적 메소드로 동작하려면 클래스 함수에 "self"를 첫 번째 인수로 전달해야합니다. "self"는 클래스의 인스턴스 변수입니다.


1
'self'는 메소드가 정적인지 아닌지를 정의합니다! 와우, 그것은이 자바 사람을위한 눈을 뜨게 해줍니다.
liwevire

25

이 코드를 사용해보십시오. 저와 같은 많은 C 프로그래머가 Py를 배우는 데 도움이되기를 바랍니다.

#! /usr/bin/python2

class Person:

    '''Doc - Inside Class '''

    def __init__(self, name):
        '''Doc - __init__ Constructor'''
        self.n_name = name        

    def show(self, n1, n2):
        '''Doc - Inside Show'''
        print self.n_name
        print 'Sum = ', (n1 + n2)

    def __del__(self):
        print 'Destructor Deleting object - ', self.n_name

p=Person('Jay')
p.show(2, 3)
print p.__doc__
print p.__init__.__doc__
print p.show.__doc__

산출:

Jay

Sum = 5

Doc - Inside Class

Doc - __init__ Constructor

Doc - Inside Show

Destructor Deleting object - Jay


나는 그것이 단지 나인지 모르겠지만이 코드를 읽는 것은 약간 혼란 스럽습니다. 어쩌면 그것은 여전히 ​​초보자 파이썬 프로그래머이기 때문일 것입니다. idk.
Linny

문서 에 대해 잘 모르겠습니다 . 문서를 가져 옵니까? 그리고 '' 'test-my doc' ''인 경우 print.p .__ test__? 또는 doc이 특정 키워드입니까?
토마스

@Thomas doc 는 문서화 된 세부 사항의 키워드입니다. 삼중 따옴표는 문서를 작성하는 데 사용되며 문서는 선택적 엔티티입니다.
Jayzcode

24

클래스 객체속성 참조와 인스턴스화 의 두 가지 작업을 지원합니다.

속성 참조 obj.name : 파이썬의 모든 속성 참조에 사용되는 표준 구문을 사용합니다. 유효한 속성 이름은 클래스 객체를 만들 때 클래스의 네임 스페이스에 있던 모든 이름입니다. 따라서 클래스 정의가 다음과 같은 경우

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

다음 MyClass.iMyClass.f각각 정수 및 함수 객체를 반환 유효한 속성 참조이다. 클래스 속성도 할당 할 수 있으므로 할당 값을 변경할 수 있습니다 MyClass.i. __doc__클래스에 속하는 docstring을 리턴하는 유효한 속성입니다 : "간단한 예제 클래스".

클래스 인스턴스화 는 함수 표기법을 사용합니다. 클래스 객체가 클래스의 새 인스턴스를 반환하는 매개 변수가없는 함수 인 척하십시오. 예를 들면 다음과 같습니다.

x = MyClass()

인스턴스화 (클래스 객체 "호출") 작업은 빈 객체를 생성합니다. 많은 클래스는 특정 초기 상태로 사용자 정의 된 인스턴스로 오브젝트를 작성하는 것을 좋아합니다. 따라서 클래스는 다음 __init__()과 같은 특수 메소드를 정의 할 수 있습니다 .

def __init__(self):
    self.data = []

클래스가 __init__()메소드를 정의하면 클래스 인스턴스화 __init__()는 새로 작성된 클래스 인스턴스에 대해 자동으로 호출됩니다 . 따라서이 예제에서 초기화 된 새로운 인스턴스는 다음과 같이 얻을 수 있습니다.

x = MyClass()

물론,이 __init__()방법에는 유연성을 높이기위한 주장이있을 수 있습니다. 이 경우 클래스 인스턴스화 연산자에 제공된 인수가에 전달됩니다 __init__(). 예를 들어

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
x.r, x.i

결국 가장 도움이 된 공식 문서 에서 가져 왔습니다 .


여기 내 예가 있습니다

class Bill():
    def __init__(self,apples,figs,dates):
        self.apples = apples
        self.figs = figs
        self.dates = dates
        self.bill = apples + figs + dates
        print ("Buy",self.apples,"apples", self.figs,"figs 
                and",self.dates,"dates. 
                Total fruitty bill is",self.bill," pieces of fruit :)")

Bill 클래스의 인스턴스를 만들 때 :

purchase = Bill(5,6,7)

당신은 얻는다 :

> Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18  pieces of
> fruit :)

22

이것을 이해하지 못하는 데 어려움이있었습니다. 여기에서 답을 읽은 후에도.

__init__방법 을 제대로 이해하려면 자신을 이해해야합니다.

자체 매개 변수

__init__메소드가 승인 한 인수 는 다음과 같습니다.

def __init__(self, arg1, arg2):

그러나 실제로 두 가지 인수 만 전달합니다.

instance = OurClass('arg1', 'arg2')

추가 논쟁은 어디에서 왔습니까?

우리가 객체의 속성에 접근 할 때 우리는 이름이나 참조로 그것을한다. 여기서 인스턴스는 새로운 객체에 대한 참조입니다. instance.printargs를 사용하여 인스턴스 객체의 printargs 메소드에 액세스합니다.

__init__메소드 내에서 객체 속성에 액세스하려면 객체에 대한 참조가 필요합니다.

메소드가 호출 될 때마다 기본 오브젝트에 대한 참조가 첫 번째 인수로 전달됩니다. 관례에 따라 항상 첫 번째 인수를 메소드 자체에 호출하십시오.

이것은 __init__우리가 할 수 있는 방법을 의미합니다 :

self.arg1 = arg1
self.arg2 = arg2

여기서는 객체의 속성을 설정합니다. 다음을 수행하여이를 확인할 수 있습니다.

instance = OurClass('arg1', 'arg2')
print instance.arg1
arg1

이와 같은 값을 객체 속성이라고합니다. 여기서 __init__메소드는 인스턴스의 arg1 및 arg2 속성을 설정합니다.

출처 : http://www.voidspace.org.uk/python/articles/OOP.shtml#the-init-method


17

참고 self실제로 유효한 파이썬 식별자 일 수있다. 예를 들어 Chris B의 예 에서처럼 쉽게 쓸 수 있습니다.

class A(object):
    def __init__(foo):
        foo.x = 'Hello'

    def method_a(bar, foo):
        print bar.x + ' ' + foo

정확히 동일하게 작동합니다. 그러나 다른 파이썬 사용자가 더 쉽게 인식 할 수 있으므로 self를 사용하는 것이 좋습니다.


본인은 foo 대신에 self를 추천하고 다른 프로그래머가 코드를
보도록

15

기본적으로 동일한 클래스 내의 여러 함수에서 변수를 사용할 때는 'self'키워드를 사용해야합니다. init 에 대해서는 해당 클래스 내에서 다른 함수가 호출되지 않은 경우 기본값을 설정하는 데 사용됩니다.


6
파이썬에는 'self'키워드가 없습니다. 첫 번째 매개 변수 'self'를 호출하는 것은 단순히 규칙입니다.
David Anderson

self는 기본적으로 자리 표시 자로 사용됩니다. 자기 자신을 사용할 필요는 없으며 "eeee"또는 "foo"또는 다른 것을 사용할 수 있습니다. 코드를 읽는 동안 다른 프로그래머에게 권장됩니다
Linny

15
  1. __init__기본적으로 특정 객체에 대해 클래스의 속성을 "초기화" / "활성화" 하여 해당 클래스와 일치 하는 함수입니다 .
  2. self 해당 속성을 상속 할 객체를 나타냅니다.

1
"self"키워드를 사용할 필요는 없으며 단지 자리 표시 자일뿐입니다. 어떤 단어라도 사용할 수 있지만 프로그램의 가독성을 돕기 위해 자기 자신을 사용하는 것이 좋습니다
Linny

13

'self'는 클래스 인스턴스에 대한 참조입니다.

class foo:
    def bar(self):
            print "hi"

이제 foo의 인스턴스를 생성하고 메소드를 호출 할 수 있습니다.이 경우 self 매개 변수는 Python에 의해 추가됩니다.

f = foo()
f.bar()

그러나 메소드 호출이 클래스 인스턴스의 컨텍스트에없는 경우에도 전달 될 수 있습니다. 아래 코드는 동일한 기능을 수행합니다.

f = foo()
foo.bar(f)

흥미롭게도 변수 이름 'self'는 단지 규칙입니다. 아래의 정의는 정확히 동일하게 작동합니다. 항상 따라야하는 매우 강력한 규칙 이라고 말했지만, 언어의 유연한 특성에 대해 말하고 있습니다.

class foo:
    def bar(s):
            print "hi"

이것이 왜 언어의 융통성에 대해 말하는가? 단지 당신이 선택한 모든 법적 이름을 변수에 줄 수 있다고 말합니다. 다른 프로그래밍 언어와 다른 점은 무엇입니까?
Daniel

내 답변에 쓴 것처럼 "bar"는 클래스 인스턴스가 첫 번째 매개 변수로 제공되는 함수 일뿐입니다. 따라서 "bar"는 "foo"에 바인딩 된 메서드로 정의되지만 다른 클래스의 인스턴스와 함께 호출 될 수도 있습니다. 예를 들어 Java에서 메소드와 "this"가 작동하는 방식은 아닙니다. 비록 이것이 동일한 개념, 함수 및 일부 인스턴스 컨텍스트 (파이썬에서 첫 번째 매개 변수 인 Java 및 "this"인 인스턴스 컨텍스트)라는 것을 알 수 있습니다. 아마도 내가 언급 한 언어의 유연성을 볼 수 있습니까?
tarn

예, 언어의 유연성을 보여줍니다. 당신이 당신의 대답을 표현하는 방식은, 당신이 "self"변수를 다른 (예를 들어 s) 라고 부를 수 있다는 사실이 파이썬의 유연성을 보여주는 것이라고 말한 것 같습니다 .
Daniel

12

질문에 대한 데모입니다.

class MyClass:

    def __init__(self):
        print('__init__ is the constructor for a class')

    def __del__(self):
        print('__del__ is the destructor for a class')

    def __enter__(self):
        print('__enter__ is for context manager')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print('__exit__ is for context manager')

    def greeting(self):
        print('hello python')


if __name__ == '__main__':
    with MyClass() as mycls:
        mycls.greeting()

$ python3 class.objects_instantiation.py
__init__ is the constructor for a class
__enter__ is for context manager
hello python
__exit__ is for context manager
__del__ is the destructor for a class

11

이 코드에서 :

class Cat:
    def __init__(self, name):
        self.name = name
    def info(self):
        print 'I am a cat and I am called', self.name

여기서는 __init__클래스의 생성자로 작동하며 객체가 인스턴스화되면이 함수가 호출됩니다. self인스턴스화 객체를 나타냅니다.

c = Cat('Kitty')
c.info()

위 진술의 결과는 다음과 같습니다.

I am a cat and I am called Kitty

11

무엇을 않는 자체가 무엇입니까? 그것은 무엇을 의미 합니까? 그것은인가 필수 ?

init를 포함한 모든 클래스 메소드의 첫 번째 인수는 항상 클래스의 현재 인스턴스에 대한 참조 입니다. 일반적으로이 인수는 항상 이름이 지정 self됩니다. init 메소드 self에서 새로 작성된 오브젝트를 나타냅니다. 다른 클래스 메서드에서는 메서드가 호출 된 인스턴스를 나타냅니다.

파이썬 " self " 를 사용하도록 강요하지 않습니다 . 원하는 이름을 지정할 수 있습니다. 그러나 메소드 정의의 첫 번째 인수는 객체에 대한 참조임을 기억 하십시오 . 파이썬 self은 당신을 위해 목록에 인수를 추가합니다 ; 메소드를 호출 할 때 포함시킬 필요는 없습니다. init 메소드에서 자체를 제공하지 않으면 오류가 발생합니다.

TypeError: __init___() takes no arguments (1 given)

뭐라고합니까 초기화 방법은 무엇입니까? 왜 필요한가요? (기타.)

init초기화가 짧습니다. 클래스의 인스턴스를 만들 때 호출되는 생성자이며 필요하지 않습니다 . 그러나 일반적으로 객체의 기본 상태를 설정하기 위해 init 메소드를 작성하는 것이 좋습니다. 처음에 객체의 상태를 설정하지 않으려면이 방법을 작성할 필요가 없습니다.


8
# Source: Class and Instance Variables
# https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables

class MyClass(object):
    # class variable
    my_CLS_var = 10

    # sets "init'ial" state to objects/instances, use self argument
    def __init__(self):
        # self usage => instance variable (per object)
        self.my_OBJ_var = 15

        # also possible, class name is used => init class variable
        MyClass.my_CLS_var = 20


def run_example_func():
    # PRINTS    10    (class variable)
    print MyClass.my_CLS_var

    # executes __init__ for obj1 instance
    # NOTE: __init__ changes class variable above
    obj1 = MyClass()

    # PRINTS    15    (instance variable)
    print obj1.my_OBJ_var

    # PRINTS    20    (class variable, changed value)
    print MyClass.my_CLS_var


run_example_func()

5

파이썬 __init__self그들은 무엇을합니까?

무엇을 self합니까? 그것은 무엇을 의미합니까? 필수입니까?

뭐라고를 않는 __init__방법은 무엇입니까? 왜 필요한가요? (기타.)

주어진 예제가 올바르지 않으므로이를 기반으로 올바른 예제를 작성하겠습니다.

class SomeObject(object):

    def __init__(self, blah):
        self.blah = blah

    def method(self):
        return self.blah 

객체의 인스턴스를 만들면 __init__객체가 생성 된 후 객체를 사용자 정의하기 위해 가 호출됩니다. 즉, 아래를 호출 SomeObject하면 'blah'(아무것이든 가능) __init__인수로 함수에 전달됩니다 blah.

an_object = SomeObject('blah')

self인수의 인스턴스 SomeObject가이 할당됩니다 an_object.

나중에이 객체에서 메소드를 호출 할 수 있습니다.

an_object.method()

점으로 구분 된 검색을 수행하면 an_object.method인스턴스가 함수의 인스턴스에 바인딩되고 메소드 (위에서 호출 한대로)가 이제 "바운드 된"메소드입니다. 즉, 인스턴스를 메소드 호출에 명시 적으로 전달할 필요가 없습니다. .

메소드 호출은 점으로 구성된 조회에서 바인딩 되었기 때문에 인스턴스를 가져오고 호출되면 수행하도록 프로그래밍 된 코드를 실행합니다.

암시 적으로 전달 된 self인수는 self규칙에 의해 호출 됩니다. 우리는 다른 합법적 인 파이썬 이름을 사용할 수 있지만 다른 파이썬 프로그래머가 다른 것으로 바꾸면 지칠 수 있습니다.

__init__파이썬 데이터 모델 문서에 문서화 된 특별한 방법 입니다. 인스턴스가 생성 된 직후에 호출됩니다 ( 불변의 데이터 유형을 서브 클래스 화하지 않는 한 필수는 아니지만 일반적으로 __new__- 를 통해 __new__).


3

여기, 그 사람은 꽤 잘 쓰고 간단하게 작성했습니다 : https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/

이에 대한 참조로 위의 링크를 읽으십시오.

self? 그렇다면 모든 고객 방법에 대한 자체 매개 변수는 무엇입니까? 무엇입니까? 물론 그것이 바로 인스턴스입니다! 다시 말하면, 인출과 같은 방법은 일부 추상 고객의 계좌에서 돈을 인출하기위한 지침을 정의합니다. jeff.withdraw (100.0)를 호출하면 해당 지시 사항이 jeff 인스턴스에 사용됩니다.

def withdraw (self, amount) :라고 말하면 "고객 객체 (자기라고 부릅니다)와 달러 수치 (금액이라고 부릅니다)에서 돈을 인출하는 방법은 다음과 같습니다. 철회가 요구되는 고객의 사례입니다. 나도 유사점이 아닙니다 jeff.withdraw (100.0)는 Customer.withdraw (jeff, 100.0)의 축약 형입니다. 암호.

init self는 다른 방법에는 의미가 있지만 init는 어떻습니까? init 을 호출 하면 객체를 만드는 과정에 있으므로 어떻게 자기를 가질 수 있습니까? 파이썬은 객체가 정확하게 맞지 않더라도 자체 패턴을 확장 할 수 있도록합니다. jeff = Customer ( 'Jeff Knupp', 1000.0)가 jeff = Customer (jeff, 'Jeff Knupp', 1000.0)를 호출하는 것과 같다고 상상해보십시오. 전달 된 제프도 결과가됩니다.

이것이 init 을 호출 할 때 self.name = name과 같은 것을 말함으로써 객체를 초기화하는 이유 입니다. self는 인스턴스이므로 jeff.name = 'Jeff Knupp와 같은 jeff.name = name과 같습니다. 마찬가지로 self.balance = balance는 jeff.balance = 1000.0과 같습니다. 이 두 줄 이후에는 Customer 객체가 "초기화되어"사용할 준비가 된 것으로 간주합니다.

당신이 무엇을 조심 __init__

초기화가 완료 호출자는 당연히 객체가 사용할 준비가되어 있음을 가정 할 수있다. 즉, jeff = Customer ( 'Jeff Knupp', 1000.0) 이후에 jeff에 대한 입금 및 출금을 시작할 수 있습니다. jeff는 완전히 초기화 된 객체입니다.

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