Computer >> Máy Tính >  >> Lập trình >> Python

Python TypeError:Đối tượng ‘NoneType’ không thể lặp lại Giải pháp

Với Python, bạn chỉ có thể lặp qua một đối tượng nếu đối tượng đó có giá trị. Điều này là do các đối tượng có thể lặp lại chỉ có một mục tiếp theo có thể được truy cập nếu giá trị của chúng không bằng Không. Nếu bạn cố gắng lặp lại trên một đối tượng Không có, bạn gặp phải TypeError: ‘NoneType’ object is not iterable lỗi.

Trong hướng dẫn này, chúng tôi nói về lỗi này có nghĩa là gì và tại sao bạn có thể gặp phải nó. Chúng tôi đi qua một ví dụ để giúp bạn giải quyết cách giải quyết lỗi Python phổ biến này.

TypeError:Đối tượng ‘NoneType’ không thể lặp lại

Để một đối tượng có thể lặp lại, nó phải chứa một giá trị. Giá trị None không thể lặp lại vì nó không chứa bất kỳ đối tượng nào. Không có giá trị nào là null.

Có sự khác biệt giữa đối tượng Không có và đối tượng rỗng có thể lặp lại. Lỗi này không được nêu ra nếu bạn có bất kỳ danh sách trống hoặc một chuỗi nào.

Điều này là do danh sách và chuỗi có kiểu dữ liệu có thể lặp lại. Khi trình thông dịch Python gặp một danh sách trống, nó sẽ không lặp lại vì không có giá trị nào. Python không thể lặp qua giá trị Không có gì nên trình thông dịch trả về lỗi.

Lỗi này thường gặp khi bạn khai báo một hàm và quên trả về một giá trị.

Một tình huống mẫu

Hãy viết một chương trình lấy danh sách tên học sinh và lọc ra những tên bắt đầu bằng “E”. Chúng tôi sẽ in các giá trị đó vào bảng điều khiển.

Bắt đầu bằng cách xác định một hàm lọc ra tên của sinh viên:

81% người tham gia cho biết họ cảm thấy tự tin hơn về triển vọng công việc công nghệ của mình sau khi tham gia một cuộc thi đào tạo. Kết hợp với bootcamp ngay hôm nay.

Sinh viên tốt nghiệp bootcamp trung bình đã dành ít hơn sáu tháng để chuyển đổi nghề nghiệp, từ khi bắt đầu bootcamp đến khi tìm được công việc đầu tiên của họ.

def filter_students(class_names):
	new_class_names = []
	for c in class_names:
		if c.startswith("E"):
			new_class_names.append(c)

Hàm này lặp qua mọi mục trong danh sách “class_names” bằng vòng lặp for. Đối với mỗi mục, vòng lặp của chúng tôi sẽ kiểm tra xem mục có bắt đầu bằng chữ cái “E” hay không. Nếu đúng, tên đó sẽ được thêm vào danh sách “new_class_names”.

Tiếp theo, viết một hàm đi qua danh sách mới của chúng tôi và in ra từng giá trị vào bảng điều khiển:

def show_students(class_names):
	for c in class_names:
		print(c)

Tại đây, chúng tôi khai báo danh sách các sinh viên mà chương trình của chúng tôi sẽ tìm kiếm thông qua đó. Chúng tôi chuyển danh sách sinh viên này thông qua hàm filter_students của chúng tôi:

students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

Mã này thực thi hàm filter_students để tìm tất cả các học sinh có tên bắt đầu bằng “E”. Danh sách các sinh viên có tên bắt đầu bằng “E” được gọi là student_e_name. Tiếp theo, chúng tôi gọi hàm show_students để hiển thị danh sách sinh viên mới:

show_students(students_e_name)

Hãy chạy mã của chúng tôi và xem điều gì sẽ xảy ra:

Traceback (most recent call last):
  File "main.py", line 14, in <module>
	show_students(students_e_name)
  File "main.py", line 8, in show_students
	for c in class_names:
TypeError: 'NoneType' object is not iterable

Mã của chúng tôi trả về một thông báo lỗi.

Giải pháp

Khi chúng tôi cố gắng lặp lại các biến class_names trong hàm show_students, mã của chúng tôi sẽ phát hiện ra giá trị Không có và tạo ra lỗi. Điều này là do giá trị mà chúng ta đã chuyển dưới dạng “class_names” là Không có.

Lỗi này là do hàm filter_students của chúng tôi không trả về giá trị. Khi chúng ta gán kết quả của hàm filter_students cho biến Students_e_name, giá trị None được đặt.

Để giải quyết lỗi này, chúng tôi phải trả về một giá trị trong hàm filter_students:

def filter_students(class_names):
	new_class_names = []
	for c in class_names:
		if c.startswith("E"):
			new_class_names.append(c)
      # We have added a return statement here
	return new_class_names
        
def show_students(class_names):
	for c in class_names:
		print(c)
    
students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

show_students(students_e_name)

Đoạn mã này trả về giá trị của new_class_names trở lại chương trình chính.

Hãy chạy mã của chúng tôi để xem nó có hoạt động không:

Elena

Mã của chúng tôi hiện đã in thành công tên của những học sinh có tên bắt đầu bằng “E”.

Tránh ngoại lệ NoneType

Về mặt kỹ thuật, bạn có thể tránh ngoại lệ NoneType bằng cách kiểm tra xem giá trị có bằng Không trước khi bạn lặp lại giá trị đó. Hãy xem xét đoạn mã sau:

def filter_students(class_names):
	new_class_names = []
	for c in class_names:
		if c.startswith("E"):
			new_class_names.append(c)
	return new_class_names

def show_students(class_names):
	if class_names is not None:
		for c in class_names:
			print(c)
            
students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

show_students(students_e_name)

Hàm “show_students ()” thực thi thành công vì chúng tôi kiểm tra xem class_names có phải là giá trị Không trước khi chúng tôi cố gắng lặp lại nó. Đây không phải là phương pháp hay nhất trong hầu hết các trường hợp vì nguyên nhân của lỗi NoneType có thể là sự cố ở một nơi khác trong mã của bạn.

Nếu chúng tôi thêm dấu kiểm “không phải là Không có” vào chương trình đầy đủ của mình, chúng tôi không biết rằng chúng tôi đã bỏ lỡ câu lệnh trả về trong một hàm khác. Đó là lý do tại sao nếu bạn gặp lỗi này, tốt nhất bạn nên chấp nhận ngoại lệ thay vì xử lý nó bằng cách sử dụng kiểm tra “không phải là Không có”.



Kết luận

Đối tượng TypeError: ‘NoneType’ object is not iterable lỗi được đưa ra khi bạn cố gắng lặp qua một đối tượng có giá trị bằng Không.

Để giải quyết lỗi này, hãy đảm bảo rằng bất kỳ giá trị nào bạn cố gắng lặp lại đều đã được gán một đối tượng có thể lặp lại, như một chuỗi hoặc một danh sách. Trong ví dụ của chúng tôi, chúng tôi đã quên thêm câu lệnh “return” vào một hàm. Điều này làm cho hàm trả về Không có thay vì một danh sách.

Bây giờ, bạn đã sẵn sàng để giải quyết lỗi Python phổ biến này bằng mã của riêng bạn.