Làm thế nào để chuyển đổi Nonetype thành int hoặc string?


96

Tôi có một Nonetypegiá trị x, nó thường là một con số, nhưng có thể là như vậy None. Tôi muốn chia nó cho một số, nhưng Python tăng:

TypeError: int() argument must be a string or a number, not 'NoneType'

Làm sao tôi có thể giải quyết việc này?


5
Giả sử rằng None tương đương với 2771. Nhưng có lẽ đó không phải là điều bạn muốn. Vui lòng cung cấp thêm thông tin.
JoshD 14/10/10

Bằng cách nào đó, tôi nhận được một giá trị Nonetype, nó phải là một int, nhưng bây giờ nó là một đối tượng Nonetype và tôi cần chia một số khác, sau đó lỗi xuất hiện.
user469652

int(None)ném một ngoại lệ vì Không có không thể được chuyển đổi thành một int. Câu trả lời cho câu hỏi của bạn là nó không thể được thực hiện. Bạn có thể thay thế một cái gì đó, chẳng hạn như 0, 2771, hoặc một con voi màu hồng, nhưng bất cứ thay thế nào, bạn vẫn không thể chuyển Không có thành số nguyên.
snapshoe

7
@ ma3204. chuyển đổi Noneđến một con voi màu hồng là không tốt, hoặc, trừ khi bạn đang làm việc một số hệ thống con số đó chính thức xác định phân chia của một số bằng một con voi màu hồng (và bạn đã viết đoạn code để sao lưu nó lên)
aaronasterling

Câu trả lời:


49

Trong một trong các nhận xét, bạn nói:

Bằng cách nào đó, tôi nhận được một giá trị Nonetype, nó phải là một int, nhưng bây giờ nó là một đối tượng Nonetype

Nếu đó là mã của bạn, hãy tìm ra cách bạn nhận được Nonekhi bạn mong đợi một con số và ngăn điều đó xảy ra.

Nếu đó là mã của người khác, hãy tìm hiểu các điều kiện mà nó đưa ra Nonevà xác định một giá trị hợp lý để sử dụng cho mã đó, với mã điều kiện thông thường:

result = could_return_none(x)

if result is None:
    result = DEFAULT_VALUE

... hoặc thậm chí ...

if x == THING_THAT_RESULTS_IN_NONE:
    result = DEFAULT_VALUE
else:
    result = could_return_none(x) # But it won't return None, because we've restricted the domain.

Không có lý do gì để tự động sử dụng 0ở đây - các giải pháp phụ thuộc vào độ "sai" của Nonegiả định bạn sẽ muốn điều này. Các DEFAULT_VALUE(nếu nó thậm chí còn tồn tại) hoàn toàn phụ thuộc vào mục đích của mã của bạn.


5
+1 cho giải pháp "đúng". Nếu cửa sổ của bạn thường xuyên phá vỡ một cách bí ẩn, con hiểu tại sao (và bắt phá hoại người chịu trách nhiệm) thay vì ngăn chặn các cửa sổ lên;)

3
Điều này không hữu ích trong trường hợp bạn đang truy xuất các khóa từ từ điển redis chẳng hạn, vì các khóa bị thiếu sẽ là Không có. Nếu bạn muốn tính tổng chúng bất kể sự hiện diện của chúng (đó là hành vi hoàn toàn có thể chấp nhận được), bạn có thể cần chuyển Không có thành 0 (xem câu trả lời kindall)
spider

1
@spider - điều đó vẫn có nghĩa là nó phụ thuộc nhiều vào tình huống và "xác định giá trị hợp lý" vẫn được áp dụng.
detly

Ý kiến ​​của Spider khá hợp lệ, câu trả lời này về cơ bản chỉ nói rằng bạn đã làm sai điều gì đó, nhưng Không có không có nghĩa là nó có nghĩa là giá trị không xác định, điều đó có thể cho thấy bạn đã làm điều gì đó sai hoặc như spider đề xuất một giá trị bị thiếu, nói chung nó phải là 0 hoặc có thể là 1, đối với hầu hết các trường hợp có thể sử dụng Không có trong đó số nguyên được mong đợi.
Glen Fletcher

@glenflet Nếu bạn không biết miền đầu vào và đặc điểm kỹ thuật của hàm của mình là gì, một người lạ trên internet sẽ không thể nói cho bạn biết. Nếu bạn biết, nhưng không biết cú pháp để chuyển đổi nó, đó là một câu hỏi hoàn toàn khác với câu hỏi được hỏi ở đây.
detly

312
int(value or 0)

Điều này sẽ sử dụng 0 trong trường hợp bạn cung cấp bất kỳ giá trị nào mà Python xem xét False, chẳng hạn như Không có, 0, [], "", v.v. Vì là 0 False, bạn chỉ nên sử dụng 0 làm giá trị thay thế (nếu không, bạn sẽ tìm thấy các số 0 của mình biến thành giá trị đó).

int(0 if value is None else value)

Giá trị này chỉ thay thế Nonebằng 0. Vì chúng tôi đang thử nghiệm Nonecụ thể, bạn có thể sử dụng một số giá trị khác để thay thế.


64
user469652 thay vào đó bạn nên xem xét việc đặt câu trả lời này thành câu trả lời được chấp nhận. nó thực sự hữu ích như trái ngược với condescending
galarant

Tôi không chắc liệu điều này có giải quyết được vấn đề mà người dùng đang gặp phải hay không. sử dụng không kiểu nào để thực hiện phép tính ... Tôi hiện đang lấy dữ liệu qua api phần còn lại đang trả về kiểu không chứa giá trị số. Nếu tôi đặt nó là 0 hoặc từ bỏ nó vì nó là tôi không thể làm bất cứ điều gì với nó
br3w5

2
Đây chắc chắn là câu trả lời tốt nhất, với câu hỏi, vì người dùng chỉ ra rằng Không có, nên được mong đợi, giống như có thể là một hàm, yêu cầu giá trị của thứ gì đó trả về Không để cho biết giá trị là không xác định, trong trường hợp này, Không có sẽ trở thành giá trị mặc định trong trường hợp sử dụng của nó, thường sẽ là 0. hãy xem xét izip_longest, đối số mặc định, nó là đối số khác có mặc định khác (loại chẵn), sau đó mặc định phải là Không có, sau đó thay thế bằng chuỗi mặc định, tuy nhiên. <align_n> (str, w) chỉ nhận một số nguyên cho chiều rộng.
Glen Fletcher

2
Đã sử dụng cái này và nó rất thanh lịch và giải quyết được các vấn đề của tôi.
Dan Safee

1
chúng ta có thể sử dụng (value or 0)- mà không có sự đúc int loại - nếu chúng ta đảm bảo giá trị mà chỉ có thể là None hoặc một int
hashlash

16

Một cách phổ biến của "Pythonic" để xử lý loại tình huống này được gọi là EAFP vì "Xin tha thứ dễ hơn xin phép ". Điều này thường có nghĩa là viết mã giả định rằng mọi thứ đều ổn, nhưng sau đó gói nó bằng một try..exceptkhối để đề phòng khi xử lý mọi thứ khi nó không ổn.

Đây là kiểu mã hóa được áp dụng cho vấn đề của bạn:

try:
    my_value = int(my_value)
except TypeError:
    my_value = 0  # or whatever you want to do

answer = my_value / divisor

Hoặc có lẽ đơn giản hơn và nhanh hơn một chút:

try:
    answer = int(my_value) / divisor
except TypeError:
    answer = 0

Cách tiếp cận nghịch đảo và truyền thống hơn được gọi là LBYL , viết tắt của " Nhìn trước khi bạn nhảy vọt " là những gì @Soviut và một số người khác đã đề xuất. Để biết thêm thông tin về chủ đề này, hãy xem câu trả lời của tôi và các nhận xét liên quan đến câu hỏi Xác định xem khóa có trong từ điển ở nơi khác trên trang web này hay không.

Một vấn đề tiềm ẩn với EAFP là nó có thể che giấu thực tế là có gì đó không ổn với một số phần khác của mã hoặc mô-đun bên thứ ba mà bạn đang sử dụng, đặc biệt là khi các trường hợp ngoại lệ thường xuyên xảy ra (và do đó không thực sự là trường hợp "ngoại lệ" ở tất cả).


11

Điều đó TypeErrorchỉ xuất hiện khi bạn cố gắng vượt qua int() None(đó là NoneTypegiá trị duy nhất , theo như tôi biết). Tôi muốn nói rằng mục tiêu thực sự của bạn không phải là chuyển đổi NoneTypethành inthoặc str, mà là tìm ra vị trí / lý do tại sao bạn nhận được Nonethay vì một con số như mong đợi, và sửa nó hoặc xử lý Noneđúng cách.


Việc vượt qua int()một số phức, chẳng hạn như int(1+2j), cũng sẽ làm tăng một số TypeError, mặc dù phải thừa nhận rằng điều đó có thể rất khó xảy ra. Bất kể, tôi nghĩ bạn nói sẽ là, không cần thắc mắc, nói chung là lời khuyên tốt để làm theo.
martineau

5

Trong Python 3, bạn cũng có thể sử dụng từ khóa "hoặc". Cách này:

foo = bar or 0
foo2 = bar or ""

2

Tôi đã sử dụng thành công int (x hoặc 0) cho loại lỗi này, miễn là Không có gì phải tương đương với 0 trong logic. Lưu ý rằng điều này cũng sẽ giải quyết thành 0 trong các trường hợp khác khi kiểm tra x trả về Sai. ví dụ: danh sách trống, tập hợp, từ điển hoặc chuỗi độ dài bằng không. Xin lỗi, Kindall đã đưa ra câu trả lời này.


1

Điều này có thể xảy ra nếu bạn quên trả về một giá trị từ một hàm: nó sẽ trả về Không có. Xem xét tất cả các vị trí bạn đang gán cho biến đó và xem liệu một trong số chúng có phải là lệnh gọi hàm mà hàm thiếu câu lệnh trả về hay không.


1
... hoặc hàm có một hoặc nhiều câu lệnh trả về chỉ đơn giản returnthay vì return some_expression.
John Machin 14/10/10

... hoặc chức năng chứa một hoặc nhiều return Nonebáo cáo
John Machin

1

Bạn nên kiểm tra để đảm bảo rằng giá trị không phải là Không có trước khi thử thực hiện bất kỳ phép tính nào trên đó:

my_value = None
if my_value is not None:
    print int(my_value) / 2

Lưu ý: my_value đã được cố ý đặt thành Không có để chứng minh mã hoạt động và việc kiểm tra đang được thực hiện.


1
bạn nên sử dụng sự so sánh sắc ( is [not] None)
shylent

-4 Bạn nên khuyến khích OP tìm ra vấn đề thực sự của họ thay vì né tránh nó. @Shylent đã nói gì. Bạn đặt my_valuevô điều kiện thành Không có; tại sao? Bạn không đặt câu hỏi tại sao OP nghĩ rằng anh ta cần làm int(my_value)khi my_value(nếu không phải Không có) "nói chung là một số".
John Machin,

1
Tôi đặt my_value thành Không như một bằng chứng về khái niệm, để hiển thị mã của tôi không bị lỗi. Tôi không đặt câu hỏi về OP bởi vì có nhiều lý do tại sao một giá trị có thể không phải lúc nào cũng là một số và kiểm tra xem nó có phải là số trước khi thực hiện các phép tính hay không. Không có gì sai khi chỉ cần trả lời câu hỏi của OP, tôi không cần phải làm tất cả bài tập về nhà cho họ.
Soviut 14/10/10

1

Tôi đã gặp vấn đề tương tự khi sử dụng các chức năng email python. Dưới đây là đoạn mã mà tôi đang cố gắng truy xuất chủ đề email vào một biến. Điều này hoạt động tốt đối với hầu hết các email và biến được điền vào. Nếu bạn nhận được email từ Yahoo hoặc loại tương tự và người gửi không điền dòng chủ đề Yahoo sẽ không tạo dòng tiêu đề trong email và bạn sẽ nhận được NoneType trả về từ chức năng. Martineau cũng như Soviut đã đưa ra một câu trả lời chính xác. Câu trả lời của IMO Soviut ngắn gọn hơn từ quan điểm lập trình; không nhất thiết phải từ Python. Đây là một số mã để hiển thị kỹ thuật:

import sys, email, email.Utils 

afile = open(sys.argv[1], 'r')    
m = email.message_from_file(afile)    
subject = m["subject"]

# Soviut's Concise test for unset variable.

if subject is None:    
     subject = "[NO SUBJECT]"

# Alternative way to test for No Subject created in email (Thanks for NoneThing Yahoo!)

try:    
    if len(subject) == 0:    
        subject = "[NO SUBJECT]"

except TypeError:    
    subject = "[NO SUBJECT]"

print subject

afile.close()

1

Trong một số trường hợp, sẽ hữu ích khi có một hàm chuyển Không có thành số không:

def nz(value):

    '''
    Convert None to int zero else return value.
    '''

    if value == None:
        return 0
    return value
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.