파이썬의 len() 메서드는 문자열, 리스트, 딕셔너리처럼 반복 가능한(iterable) 객체에만 사용할 수 있습니다. 이는 반복 가능한 객체가 값들의 시퀀스를 포함하고 있기 때문입니다. 만약 None 값을 대상으로 len() 메서드를 호출하면 "TypeError: object of type 'NoneType' has no len()" 오류가 발생합니다.
이 글에서는 해당 오류의 의미와 발생 원리를 살펴보고, 실제 코드 예제 두 가지를 통해 오류가 어떻게 나타나는지 그리고 이를 어떻게 해결할 수 있는지 단계별로 알아보겠습니다.
TypeError: object of type 'NoneType' has no len()란?
NoneType은 None 데이터 타입을 의미합니다. None 값에는 len()처럼 반복 가능한 객체에 사용되는 메서드를 적용할 수 없습니다. 그 이유는 None이 값들의 집합을 담고 있지 않기 때문입니다. None은 하위 값을 가지지 않으므로 길이를 계산하는 것 자체가 불가능합니다.
이 오류는 주로 다음 두 가지 경우에 발생합니다.
- 내장 함수가 리스트를 제자리(in-place)에서 변경한다는 사실을 잊었을 때
- 함수 내에 return 문을 작성하지 않았을 때
각각의 원인을 하나씩 자세히 살펴보겠습니다.
원인 1: 내장 함수는 리스트를 제자리에서 변경한다
학교 학생들의 정보를 담고 있는 딕셔너리 리스트를 정렬하는 프로그램을 만들어 보겠습니다. 학생들을 마지막 시험 점수 기준 오름차순으로 정렬하는 것이 목표입니다.
먼저 학생 정보와 최근 시험 점수를 담은 딕셔너리 리스트를 정의합니다.
students = [
{"name": "Peter", "score": 76 },
{"name": "Richard", "score": 63 },
{"name": "Erin", "score": 64 },
{"name": "Miley", "score": 89 }
]
각 딕셔너리는 두 개의 키와 값을 가집니다. 하나는 학생의 이름, 다른 하나는 마지막 시험에서 받은 점수에 해당합니다. 다음으로 sort() 메서드를 사용해 학생 리스트를 정렬해 보겠습니다.
def score_sort(s): return s["score"] sorted_students = students.sort(key=score_sort)
여기서 우리는 각 딕셔너리의 "score" 값을 반환하는 "score_sort" 함수를 선언했습니다. 그리고 이 함수를 sort() 메서드의 key 인자로 활용해 딕셔너리 리스트의 항목들을 정렬했습니다.
다음으로 리스트의 길이를 출력합니다.
print("There are {} students in the list.".format(len(sorted_students)))
그리고 for 루프를 사용해 정렬된 새 딕셔너리 리스트를 콘솔에 출력합니다.
for s in sorted_students:
print("{} earned a score of {} on their last test.".format(s["name"], s["score"]))
이 코드는 "sorted_students" 리스트의 각 학생마다 마지막 시험에서 몇 점을 받았는지 알려주는 메시지를 출력합니다. 코드를 실행해 보겠습니다.
Traceback (most recent call last):
File "main.py", line 13, in <module>
print("There are {} students in the list.".format(len(sorted_students)))
TypeError: object of type 'NoneType' has no len()
오류가 발생했습니다.
이 문제를 해결하려면 sort() 메서드의 결과를 "sorted_students" 변수에 할당하는 코드를 제거해야 합니다. sort() 메서드는 원본 리스트를 제자리에서 변경할 뿐, 새로운 리스트를 생성하지 않기 때문입니다.
"sorted_students" 변수 선언을 삭제하고 프로그램의 나머지 부분에서 "students"를 직접 사용하도록 수정합니다.
students.sort(key=score_sort)
print("There are {} students in the list.".format(len(students)))
for s in students:
print("{} earned a score of {} on their last test.".format(s["name"], s["score"]))
다시 코드를 실행해 결과를 확인해 보겠습니다.
There are 4 students in the list. Richard earned a score of 63 on their last test. Erin earned a score of 64 on their last test. Peter earned a score of 76 on their last test. Miley earned a score of 89 on their last test.
이번에는 코드가 성공적으로 실행됩니다. 먼저 리스트에 몇 명의 학생이 있는지 알려주고, 이어서 각 학생의 이름과 마지막 시험 점수 정보를 점수 오름차순으로 출력합니다.
원인 2: return 문 누락
이번에는 코드를 더 모듈화해 보겠습니다. 정렬 로직을 별도의 함수로 분리하고, 각 학생의 시험 점수 정보를 출력하는 함수도 함께 정의합니다.
먼저 앞서 사용한 학생 리스트와 정렬 헬퍼 함수를 정의합니다.
students = [
{"name": "Peter", "score": 76 },
{"name": "Richard", "score": 63 },
{"name": "Erin", "score": 64 },
{"name": "Miley", "score": 89 }
]
def score_sort(s):
return s["score"]
다음으로 리스트를 정렬하는 함수를 작성합니다.
def sort_list(students): students.sort(key=score_sort)
마지막으로 각 학생의 성적 정보를 화면에 표시하는 함수를 정의합니다.
def show_students(new_students):
print("There are {} students in the list.".format(len(students)))
for s in new_students:
print("{} earned a score of {} on their last test.".format(s["name"], s["score"]))
코드를 실행하기 전에 작성한 함수들을 호출해야 합니다.
new_students = sort_list(students) show_students(new_students)
프로그램은 먼저 sort_list() 함수를 사용해 리스트를 정렬한 뒤, show_students() 함수를 통해 각 학생의 정보를 콘솔에 출력합니다.
코드를 실행해 보겠습니다.
Traceback (most recent call last):
File "main.py", line 21, in <module>
show_students(new_students)
File "main.py", line 15, in show_students
print("There are {} students in the list.".format(len(new_students)))
TypeError: object of type 'NoneType' has no len()
역시 오류가 발생했습니다. 원인은 "sort_list" 함수에 return 문을 작성하지 않았기 때문입니다.
sort_list() 함수를 호출하면 그 반환값을 "new_students" 변수에 할당합니다. 이 변수는 각 학생의 정보를 출력하는 show_students() 함수로 전달됩니다. 파이썬에서 함수에 return 문이 없으면 자동으로 None을 반환하기 때문에, "new_students"에는 None이 저장된 것입니다.
이 오류를 해결하려면 sort_list() 함수에 return 문을 추가해야 합니다.
def sort_list(students): students.sort(key=score_sort) return students
다시 코드를 실행합니다.
There are 4 students in the list. Richard earned a score of 63 on their last test. Erin earned a score of 64 on their last test. Peter earned a score of 76 on their last test. Miley earned a score of 89 on their last test.
이제 코드가 기대했던 결과를 정상적으로 반환합니다.
마무리
"TypeError: object of type 'NoneType' has no len()" 오류는 값이 None인 객체에 len() 메서드를 사용하려 할 때 발생합니다.
이 오류를 해결하려면 먼저 sort() 같은 리스트 내장 메서드의 반환값을 변수에 할당하고 있지 않은지 확인하세요. 리스트를 제자리에서 변경하는 메서드는 None을 반환하므로, 원본 리스트 자체를 사용해야 합니다. 그래도 오류가 해결되지 않는다면 프로그램의 모든 함수에 필요한 return 문이 빠짐없이 작성되어 있는지 점검하세요.
이제 여러분도 파이썬 전문가처럼 이 문제를 손쉽게 해결할 수 있습니다!