2010-07-05 33 views
15

Trong python nếu bạn viết một cái gì đó giống nhưPython boolean biểu và hay

foo==bar and spam or eggs 

trăn xuất hiện trở lại thư rác nếu báo cáo kết quả boolean là đúng và trứng khác. Ai đó có thể giải thích hành vi này? Tại sao biểu thức không được đánh giá như một boolean dài?

Chỉnh sửa: Cụ thể, tôi đang cố gắng tìm ra cơ chế tại sao 'spam' hoặc 'trứng' được trả lại do kết quả của biểu thức.

Trả lời

14

Các nhà khai thác andor là chập mạch có nghĩa là nếu kết quả của biểu thức có thể được rút ra từ chỉ đánh giá đầu tiên toán hạng, thứ hai không được đánh giá. Ví dụ: nếu bạn có biểu thức a or ba đánh giá là đúng thì không quan trọng b là gì, kết quả của biểu thức là đúng để b không được đánh giá. Chúng thực sự hoạt động như sau:

  • a and b: Nếu một falsey, b không được đánh giá và trả về, nếu không b sẽ được trả về.
  • a or b: Nếu giá trị trung thực, b không được đánh giá và giá trị được trả lại, nếu không b sẽ được trả lại.

Falsey và sự thật ám chỉ giá trị đánh giá sai hoặc đúng trong ngữ cảnh boolean.

Tuy nhiên này và/hoặc thành ngữ là hữu ích trở lại trong những ngày khi không có lựa chọn tốt hơn, nhưng bây giờ có một cách tốt hơn:

spam if foo==bar else eggs 

Vấn đề với và/hoặc thành ngữ (ngoài nó gây nhầm lẫn cho người mới bắt đầu) là nó cho kết quả sai nếu điều kiện là đúng nhưng spam đánh giá thành giá trị falsey (ví dụ: chuỗi rỗng). Vì lý do này, bạn nên tránh nó.

+1

'spam nếu foo == bar hoặc trứng' hiển thị lỗi cú pháp trong python 2.6.5, nhưng 'spam if foo == bar other eggs' hoạt động như dự định. – Zxaos

+0

@Zxaos: Xin lỗi về điều đó. Nó phải là 'else' không' hoặc'. Đã sửa lỗi. –

+1

Trong "kết quả sai ... nếu foo ước tính giá trị falsey" bạn có nghĩa là "spam đánh giá thành giá trị falsey" không? – unutbu

2

Thử sử dụng dấu ngoặc đơn để làm cho biểu thức không mơ hồ. Cách nó là, bạn đang nhận được:

(foo == bar and spam) or eggs 
+0

+1 để đánh bại tôi vào nó – derekerdmann

+0

Tôi hiểu rằng nó là ngắn mạch, nhưng tôi không chắc chắn lý do tại sao spam hoặc trứng đang được trả lại là kết quả của việc đánh giá. – Zxaos

3

Lý do là Python đánh giá biểu thức boolean sử dụng các giá trị thực tế của các biến có liên quan, thay vì hạn chế chúng để TrueFalse giá trị. Các giá trị sau đây được coi là sai:

  • None
  • False
  • 0 của bất kỳ loại số
  • trống chuỗi hoặc thiết lập ('', (), [], {})
  • người dùng định nghĩa các loại với phương thức __nonzero__() hoặc __len__() trả về 0 hoặc False

Xem phần Truth Value Testing của tài liệu Python để biết thêm thông tin. Đặc biệt:

hoạt động và chức năng được xây dựng trong đó có một kết quả Boolean luôn luôn trả 0 hoặc False cho sai và 1 hoặc True cho đúng, trừ khi có quy định khác. (Ngoại lệ quan trọng:. Các hoạt động Boolean orand luôn quay trở lại một trong những toán hạng của họ)

+0

Ok, vì vậy giả sử foo và thanh bằng nhau. Sau đó, thông dịch viên sẽ đánh giá Đúng và spam, điều này sẽ được đánh giá là True, vậy tại sao thư rác lại bị trả lại? Chỉnh sửa: Ah, ok. Tôi thấy từ các tài liệu. – Zxaos

+0

@Zxaos: Tôi đã cập nhật câu trả lời của mình với trích dẫn từ tài liệu giải thích lý do tại sao. –

5

Đây là cách các toán tử logic boolean hoạt động.

Từ the documentation (đoạn cuối cùng giải thích lý do tại sao nó là một ý tưởng tốt mà các nhà khai thác làm việc theo cách họ làm):

Trong bối cảnh hoạt động Boolean, và cũng có khi biểu thức được sử dụng bởi kiểm soát báo cáo lưu chuyển, các giá trị sau được hiểu là sai: False, None, số zero của tất cả loại, và chuỗi rỗng và container (bao gồm các chuỗi, các bộ, danh sách, từ điển, bộ và frozensets). Tất cả các giá trị khác là được hiểu là đúng. (Xem __nonzero__() phương pháp đặc biệt cho một cách để thay đổi điều này.)

Nhà điều hành not mang True nếu đối số của nó là sai, False khác.

Biểu thức x and y đánh giá đầu tiên x; nếu x là sai, giá trị của nó là được trả lại; nếu không, y được đánh giá và giá trị kết quả được trả về.

Biểu thức x or y đánh giá đầu tiên x; nếu x là đúng, giá trị của nó là được trả lại; nếu không, y được đánh giá và giá trị kết quả được trả về.

(Lưu ý rằng không phải and cũng không or hạn chế giá trị và gõ họ trở về FalseTrue, nhưng thay vì trả lại luận đánh giá cuối cùng. Đây là đôi khi hữu ích, ví dụ, nếu s là một chuỗi rằng nên được thay thế bằng một giá trị mặc định nếu nó là trống rỗng, các biểu s or 'foo' mang lại giá trị mong muốn. bởi vì not phải phát minh ra một giá trị dù sao, nó không bận tâm để trả về giá trị so với cùng loại như là đối số của nó, vì vậy ví dụ, not 'foo' mang False, không ''.)

+0

+1 cho liên kết tới tài liệu. –

Các vấn đề liên quan