Đối tượng 'NoneType' là gì?


87

Tôi gặp lỗi này khi chạy tập lệnh python của mình:

TypeError: cannot concatenate 'str' and 'NoneType' objects

Tôi khá chắc chắn rằng 'str' có nghĩa là chuỗi, nhưng tôi không biết đối tượng 'NoneType' là gì. Tập lệnh của tôi nằm ở dòng thứ hai, tôi biết dòng đầu tiên hoạt động vì các lệnh từ dòng đó nằm trong asa của tôi như tôi mong đợi. Lúc đầu, tôi nghĩ có thể là do tôi đang sử dụng các biến và đầu vào của người dùng bên trong send_command.

Mọi thứ trong 'CAPS' đều là biến, mọi thứ trong 'chữ thường' đều được nhập từ các tùy chọn 'parser.add_option'.

Tôi đang sử dụng pexpect và optparse

send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
send_command(child, SNMPSRVUSRCMD + snmpuser + group + V3AUTHCMD + snmphmac + snmpauth + PRIVCMD + snmpencrypt + snmppriv)

2
Chúng ta cần phải xem chi tiết mã số và đầu vào - phương tiện NoneTyoe rằng một trong những biến vẫn chưa được thiết lập
mmmmmm

3
NoneTypelà loại giá trị singleton None. Một trong các giá trị của bạn không phải là một chuỗi.
Martijn Pieters

Nhanh & Dirty: đưa từng hạn để concatenate trong str()str (SNMPSRVUSRCMD) + str (snmpuser) + ...
PeterMmm

2
@PeterMmm Đó là một ý tưởng khủng khiếp - vấn đề sẽ chỉ tự bộc lộ (có lẽ còn tồi tệ hơn). Sẽ tốt hơn nếu tìm ra lý do tại sao một trong các biến là Không có để bắt đầu.
arshajii

Câu trả lời:


82

NoneTypelà kiểu cho Noneđối tượng, là một đối tượng cho biết không có giá trị . Nonelà giá trị trả về của các hàm "không trả về gì cả". Nó cũng là một giá trị trả về mặc định chung cho các hàm tìm kiếm thứ gì đó và có thể tìm thấy hoặc không tìm thấy nó; ví dụ, nó được trả về re.searchkhi regex không khớp hoặc dict.getkhi khóa không có mục nhập trong dict. Bạn không thể thêm Nonevào chuỗi hoặc các đối tượng khác.

Một trong các biến của bạn là None, không phải là một chuỗi. Có thể bạn đã quên returnmột trong các chức năng của mình hoặc có thể người dùng không cung cấp tùy chọn dòng lệnh và optparsecung cấp cho bạn Nonegiá trị của tùy chọn đó. Khi bạn cố gắng thêm Nonevào một chuỗi, bạn nhận được ngoại lệ:

send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)

Một trong grouphoặc SNMPGROUPCMDhoặc V3PRIVCMDNonekhi giá trị của nó.


Cảm ơn!! Bạn đúng ở đâu, một trong những tùy chọn nhập liệu người dùng của tôi không được sử dụng vì một số lý do. Tôi đã thêm điều này làm "tên" so với một tùy chọn và bùng nổ, nó đã hoạt động. Bây giờ tôi chỉ cần tìm hiểu lý do tại sao điều này không được coi là một tùy chọn đúng cách, tất cả các tùy chọn khác đều hoạt động tốt.
không an toàn-CNTT

1
"Not set" hơi mơ hồ ... nếu một biến không được xác định và bạn cố gắng thực hiện một số thao tác với nó, bạn sẽ nhận được a NameError. Nó cũng có thể được đặt, nhưng bằng None("set to nothing" = "not set"?), Thì bạn có thể nhận được một số TypeError.
Nick T

Về cơ bản (dành cho dân C / Java ở đây) none = null
Zoe

23

NoneTypechỉ đơn giản là loại Nonesingleton:

>>> type(None)
<type 'NoneType'>

Từ liên kết sau ở trên:

None

Giá trị duy nhất của loại NoneType. Nonethường được sử dụng để biểu thị sự vắng mặt của một giá trị, như khi các đối số mặc định không được truyền cho một hàm. Chuyển nhượng Nonelà bất hợp pháp và tăng a SyntaxError.

Trong trường hợp của bạn, có vẻ như một trong những mục bạn đang cố gắng nối None, do đó lỗi của bạn.


21

Vì lợi ích của việc lập trình phòng thủ, các đối tượng phải được kiểm tra tính vô hiệu trước khi sử dụng.

if obj is None:

hoặc là

if obj is not None:

2
"is" chỉ nên được sử dụng nếu bạn cần. Lập trình phòng thủ tốt nhất là các bài kiểm tra, rất nhiều bài kiểm tra.
Jürgen A. Erhard

2
Lập trình phòng thủ là một trong những điều xấu xa nhất. Nếu bạn tìm thấy một lỗi như vậy, điều này có nghĩa là bạn đã lập trình sai. Những thứ như "kiểm tra null trước khi sử dụng" chỉ ẩn một số lỗi nghiêm trọng. Bạn nên để ngoại lệ được ném. Và đừng bắt các lập trình viên ném một số ngoại lệ tùy chỉnh, nó thực sự rất cồng kềnh. Hãy để lỗi tự nhiên được ném ra. Trên thực tế, lập trình phòng thủ là một dấu hiệu cho thấy bạn nên sử dụng một ngôn ngữ khác.
bzim

Tôi truy vấn cơ sở dữ liệu qua sqlAlchemy. Không có kết quả. Đối tượng trả về là Không có. Có nghĩa là không có kết quả. Không có lỗi. Bạn kiểm tra xem có kết quả không, nếu không, bạn sử dụng đối tượng kết quả. Không có gì xấu xa về nó. Điều xấu xa nhất của lập trình là chủ nghĩa giáo điều.
100

17

Nó có nghĩa là bạn đang cố gắng nối một chuỗi với một cái gì đó None.

Không có "null" của Python và NoneTypelà kiểu của nó.

Mã này sẽ phát sinh cùng một loại lỗi:

>>> bar = "something"
>>> foo = None
>>> print foo + bar
TypeError: cannot concatenate 'str' and 'NoneType' objects


2

Trong thông báo lỗi, thay vì cho bạn biết rằng bạn không thể nối hai đối tượng bằng cách hiển thị giá trị của chúng (một chuỗi và Nonetrong ví dụ này), trình thông dịch Python cho bạn biết điều này bằng cách hiển thị các loại đối tượng mà bạn đã cố gắng nối. Kiểu của mọi chuỗi strtrong khi kiểu của Nonecá thể đơn lẻ được gọi NoneType.

Thông thường bạn không cần quan tâm đến bản thân NoneType, nhưng trong ví dụ này, bạn cần phải biết điều đó type(None) == NoneType.


Tôi có một vấn đề rất giống nhau và cố gắng để phát hiện nếu đối tượng là NoneType, khẳng định mình không làm việc cho tôi: >>> type(key) <type 'NoneType'> >>> type(key) == NoneType Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'NoneType' is not defined
Rubick

2
@RuBiCK NoneTypekhông được xác định ở bất kỳ đâu (mà tôi biết). Nếu bạn muốn kiểm tra xem một giá trị có phải là không None, chỉ cần sử dụng key is None(xem stackoverflow.com/questions/23086383/… ). Nếu không, bạn có thể sử dụng type(key) == type(None)để có hiệu quả tương tự.
Feuermurmel

1

Lỗi của bạn xảy ra do một cái gì đó như sau: >>>
>>> None + "hello world"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

Đối tượng None của Python gần tương đương với null , nil , v.v. trong các ngôn ngữ khác.


0

Một trong các biến không được cung cấp bất kỳ giá trị nào, do đó, nó là một NoneType. Bạn sẽ phải xem tại sao lại như vậy, có thể đó là một lỗi logic đơn giản từ phía bạn.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.