Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python NameError: 'self' 이름이 정의되지 않았습니다 오류 해결 가이드

Python에서 "self" 값은 메서드가 호출되고 지정될 때만 메서드 내부에서 접근할 수 있습니다.

메서드에 지정된 다른 인수 안에서 "self"에 접근할 수 없으며, "self"를 인수로 받지 않은 함수 내부에서도 사용할 수 없습니다. 이 규칙을 어기면 NameError: name 'self' is not defined 오류가 발생합니다.

이 글에서는 해당 오류의 의미와 발생 원인을 설명하고, 실제 코드 예제를 통해 오류를 해결하는 방법을 단계별로 알아보겠습니다.

NameError: name 'self' is not defined란?

"self" 변수는 클래스 내부의 객체에 대한 정보를 담고 있습니다. 객체에 할당된 모든 값은 "self" 변수를 통해 접근할 수 있습니다.

메서드 내부에서 "self"를 사용하려면 반드시 인수로 전달해야 합니다. "self"는 메서드 내부에서만 접근 가능한 변수이므로, 메서드의 다른 인수 목록에서는 사용할 수 없습니다.

다음 두 가지 경우에 이 오류를 만나게 됩니다.

  • 메서드의 인수로 "self"를 지정하지 않은 경우
  • 인수 목록에서 다른 인수의 기본값으로 "self"를 사용한 경우

각 시나리오를 하나씩 자세히 살펴보겠습니다.

시나리오 1: "self"가 인수로 지정되지 않은 경우

메서드 내부에서 "self"에 접근하려면 반드시 인수 목록에 포함되어야 합니다. "self"는 전역 변수가 아니라 클래스 내부에서만 유효한 지역 변수이기 때문입니다.

영화 정보를 담는 클래스를 가진 프로그램을 작성해 보겠습니다. 먼저 영화 관련 값을 저장하는 생성자와 함께 클래스를 정의합니다.

class Movie:
def __init__(self, name, year_released):
self.name = name
self.year_released = year_released

이 클래스는 영화 이름(name)과 개봉 연도(year_released)라는 두 가지 값을 저장할 수 있습니다. 다음으로 개봉 연도를 변경할 수 있는 메서드를 선언합니다.

	def change_year(year_released):
self.year_released = year_released
print("{} was released in {}.".format(self.name, self.year_released))

코드를 테스트하기 위해 클래스의 객체를 생성합니다. 이 객체는 1996년에 개봉한 영화 <해피 길모어>를 나타냅니다.

happy_gilmore = Movie("Happy Gilmore")
happy_gilmore.change_year(1996)

객체에서 change_year() 메서드를 호출하여 영화의 개봉 연도를 1996년으로 설정했습니다. 코드를 실행해 결과를 확인해 보겠습니다.

Traceback (most recent call last):
File "main.py", line 11, in <module>
happy_gilmore.change_year()
File "main.py", line 7, in change_year
self.year_released = year_released
NameError: name 'self' is not defined

코드에서 오류가 발생했습니다.

원인은 메서드에 "self"를 인수로 전달하지 않았기 때문입니다. change_year() 메서드의 첫 번째 인수로 "self"를 추가하면 오류를 해결할 수 있습니다.

def change_year(self, year_released):
self.year_released = year_released
print("{} was released in {}.".format(self.name, self.year_released))

코드를 다시 실행해 보겠습니다.

Happy Gilmore was released in 1996.

코드가 성공적으로 실행되었습니다!

시나리오 2: 다른 인수의 기본값으로 "self"를 사용한 경우

"self"는 함수가 호출되는 시점에 평가됩니다. 따라서 함수의 인수 목록에서 "self"를 참조하는 기본값을 지정할 수 없습니다.

예를 들어, 개봉 연도가 지정되지 않았을 때 콘솔에 "연도가 변경되지 않았다"는 메시지를 출력하도록 메서드를 수정해 보겠습니다. 기본 인수(default argument)를 설정하여 구현할 수 있습니다.

def change_year(self, year_released=self.year_released):
if year_released != self.year_released:
self.year_released = year_released
print("{} was released in {}.".format(self.name, self.year_released))
else:
print("This movie has not been changed.")

print(year_released)

여기서 "year_released"는 기본값으로 "self.year_released"를 갖습니다. 즉, 변경할 연도를 지정하지 않으면 기본값이 사용되고, 값을 지정하면 지정한 값이 우선 적용됩니다.

지정한 값이 "self.year_released"와 다르면 개봉 연도가 변경되고, 같으면 영화가 변경되지 않았다는 메시지가 출력됩니다. if 문이 평가된 후에는 "year_released" 값이 콘솔에 출력됩니다.

코드를 실행해 보겠습니다.

Traceback (most recent call last):
File "main.py", line 1, in <module>
class Movie:
File "main.py", line 6, in Movie
def change_year(self, year_released=self.year_released):
NameError: name 'self' is not defined

오류가 다시 발생했습니다. 인수 목록의 다른 인수에서 "self"를 사용하려고 했기 때문입니다.

이 오류는 기본값을 인수 목록이 아닌 함수 본문 내부에서 설정하면 해결할 수 있습니다.

def change_year(self, year_released=None):
if year_released != self.year_released:
self.year_released = year_released
print("{} was released in {}.".format(self.name, self.year_released))
else:
year_released = self.year_released
print("This movie has not been changed.")

print(year_released)

이 코드에서는 함수 호출 시 "year_released" 값을 지정하지 않으면, 함수 내부에서 "year_released"가 "self.year_released"와 같은 값으로 설정됩니다.

새로운 Movie 객체를 생성해 코드를 테스트해 보겠습니다.

happy_gilmore = Movie("Happy Gilmore", 1995)
happy_gilmore.change_year(1996)

<해피 길모어>의 개봉 연도를 잘못 1995년으로 지정했습니다. change_year() 메서드로 이를 수정해야 합니다. 실행 결과는 다음과 같습니다.

Happy Gilmore was released in 1996.
1996

코드가 성공적으로 실행되었습니다. 이번에는 "year_released" 값이 이미 지정한 값과 동일한 경우를 테스트해 보겠습니다.

happy_gilmore = Movie("Happy Gilmore", 1996)
happy_gilmore.change_year(1996)

실행 결과는 다음과 같습니다.

This movie has not been changed.
1996

코드가 else 문을 실행하며 영화가 변경되지 않았음을 정상적으로 알려줍니다.

마무리

NameError: name 'self' is not defined 오류는 메서드의 위치 인수로 "self"를 지정하는 것을 잊었거나, 인수 목록의 다른 인수에서 "self"를 사용했을 때 발생합니다.

이 오류를 해결하려면 "self"를 사용하는 모든 메서드의 인수 목록에 "self"가 포함되어 있는지 확인하세요. 그래도 해결되지 않는다면, 어떤 인수도 기본값으로 "self"에 의존하고 있지 않은지 점검해야 합니다.

이제 프로 개발자처럼 이 Python 오류를 손쉽게 해결할 수 있습니다!