본문 바로가기
컴퓨터/Python

[파이썬] 파이썬 에러 TypeError: hello() takes 0 positional arguments but 1 was given , 파이썬 클래스에서 self를 사용하는 이유

by HanJoohyun 2017. 11. 12.
반응형


 

 

안녕하세요 한주현입니다.

 

오늘은 파이썬 클래스 생성시 흔히 볼 수 있는 오류인,

 

TypeError: hello() takes 0 positional arguments but 1 was given

 

에 대하여 알아보겠습니다.


 

 문제 상황

 

TypeError: hello() takes 0 positional arguments but 1 was given


객체지향 언어라고 하는 파이썬을 나름 배우고 나서 클래스로 멋지게 코드를 작성해보자 다짐하며


아래와 같은 코드를 작성하고 실행을 하였는데,


1
2
3
4
5
6
7
8
class MyClass():
    var1 = 10
    def hello():
        print("hello")
 
myClass1 = MyClass()
print(myClass1.var1)
print(myClass1.hello())
cs



1
2
3
4
5
10
Traceback (most recent call last):
  File "class.py", line 3in <module>
    myClass1.hello()
TypeError: hello() takes 0 positional arguments but 1 was given
cs


TypeError: hello() takes 0 positional arguments but 1 was given


왜 오류가 났을까요?

 

 



 해결 방법

 

TypeError: hello() takes 0 positional arguments but 1 was given

해결방법은 self를 클래스 안의 정의된 함수(메서드)에 아래와 같이 작성합니다.


1
2
3
4
5
6
7
8
class MyClass():
    var1 = 10
    def hello(self):
        print("hello")
 
myClass1 = MyClass()
print(myClass1.var1)
print(myClass1.hello())
cs


3번 라인에 보시면


1
def hello():
cs



1
def hello(self):
cs


로 바뀌었습니다.


파이썬 클래스에서 self를 사용하는 이유

아래 코드에서 보시면 클래스 내부의 함수(메서드)에서 첫 번째 인자로 self가 있습니다.


1
2
3
4
class MyClass():
    var1 = 10
    def hello(self):
        print("hello")
cs


이는 


파이썬에서 클래스 객체를 생성할 때 만들어진 객체가

메서드를 호출 할 때 객체 자기 자신이 인자로 들어가기 때문입니다.


그래서 첫 번째 인자인 self가 들어가지 않으면 


TypeError: hello() takes 0 positional arguments but 1 was given


hello()는 인자 받지 않는데 1개가 들어갔다 라고 오류가 나게 되는 것이지요.


여기서 1개가 들어간것은 객체 자신입니다.


그러면, 자기 자신을 가리키는 인자를 넣으면 되니 self 말고 다른 것을 넣어도 되는지 궁금증이 생깁니다.

예를 들어 self 말고 전혀 관계없어 보이는 abc를 넣어보죠.


1
2
3
4
class MyClass():
    var1 = 10
    def hello(abc):
        print("hello")
cs


그래도 코드는 잘 작동합니다.

요지는 첫 번째로 들어가는 인자가 객체 자신을 가리키는 이름이 된다는 점입니다.


어려우시죠? ㅎㅎ


우리가 프로그래밍을 할 때 일의 순서대로 진행되는 절차지향적인 관점에서 

객체지향적 관점을 갖게되는 부분이기에 어렵습니다.


간단한 예를 하나 더 볼까요?


MyClass의 메서드로 setName을 정의하였습니다.

setName 메서드는 인자로 self, name 두 개를 받습니다.


아래 코드를 보시면, 

5번 라인: MyClass클래스로 myClass1객체를 만들었습니다.


6번 라인: myClass1객체에서 사용할 수 있는 메서드들을 dir함수로 보았습니다.

setName이라고 우리가 정의한 메서드가 있군요!


10번 라인: myClass1객체의 메서드 setName을 호출하며 인자로 문자열 "Ken"을 넣었습니다.


그림으로 나타내면 이렇죠.



11번 라인: 객체 자신의 name이란 속성을 외부 인자 name으로 채워넣으니,

객체의 name속성이 생겨서 dir함수에서 name을 확인 할 수 있습니다. ㅎㅎ


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> class MyClass:
...     def setName(self, name):
...         self.name = name
... 
>>> myClass1 = MyClass()
>>> dir(myClass1)
['__class__''__delattr__'
...
'__weakref__''setName']
>>> myClass1.setName("Ken")
>>> dir(myClass1)
['__class__''__delattr__',
...
'name''setName']
>>> myClass1.name
'Ken'
>>> 
cs





오늘은 파이썬 클래스 오류 해결과 self를 왜 사용해야 하는지에 대해 알아보았습니다.


여러분들께 도움이 되셨으면 좋겠네요

그럼 다음 시간에 만나요!

 

 

 


반응형

댓글