Python `if x không phải là` hoặc` nếu không x là none`?


746

Tôi luôn nghĩ if not x is Nonephiên bản sẽ rõ ràng hơn, nhưng cả hướng dẫn về phong cách của Google và PEP-8 đều sử dụng if x is not None. Có bất kỳ sự khác biệt nhỏ nào về hiệu suất (tôi cho là không), và có trường hợp nào một người thực sự không phù hợp (làm cho người khác trở thành người chiến thắng rõ ràng cho hội nghị của tôi) không? *

* Tôi đang đề cập đến bất kỳ singleton, thay vì chỉ None.

... để so sánh những người độc thân như Không có. Sử dụng là hay không.


8
is notlà một nhà điều hành trong quyền riêng của mình. Thích !=. Nếu bạn thích not x is Nonethì bạn cũng nên thích not a == bhơn a != b.
Tomasz Gandor

@TomaszGandor Tôi không còn ý kiến ​​này nữa not x is None(câu trả lời ở đây đã thuyết phục tôi) - tuy nhiên, đáng chú ý not a == blà phong cách ưa thích trong Python, so với a != b.
orokusaki

4
@orokusaki có not a == bthực sự là phong cách ưa thích? Tôi chưa bao giờ thấy nó được thực hiện theo cách đó và ở mọi nơi tôi nhìn mọi người đều sử dụng !=.
Mike - SMT

2
@orokusaki Trong tính dễ đọc của Python, do đó, đây là kiểu ưa thích để sử dụng một toán tử !=thay vì hai toán tử not, ==.
Jeyekomon

Câu trả lời:


995

Không có sự khác biệt về hiệu năng, khi chúng biên dịch theo cùng một mã byte:

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

Theo phong cách, tôi cố gắng tránh not x is y. Mặc dù trình biên dịch sẽ luôn coi nó là not (x is y), nhưng một người đọc có thể hiểu nhầm cấu trúc là (not x) is y. Nếu tôi viết x is not ythì không có sự mơ hồ.


103
Trừ khi cùng một người đọc nghĩ rằng nó là x is (not y). Nhưng tôi có xu hướng đồng ý với bạn cho lý do khác của bạn.
Etaoin

24
ngoài ra "không phải là" ít mơ hồ hơn trong bối cảnh này "nếu a không phải là Không và b là Không có:" vs "nếu không phải là Không và b là Không có:"
Gordon Wrigley

45
toán tử phải là "aint"
bean

217

Cả hướng dẫn về phong cách của Google và Python là cách thực hành tốt nhất:

if x is not None:
    # Do something about x

Sử dụng not xcó thể gây ra kết quả không mong muốn.

Xem bên dưới:

>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0]         # You don't want to fall in this one.
>>> not x
False

Bạn có thể quan tâm để xem những gì chữ được đánh giá Truehoặc Falsetrong Python:


Chỉnh sửa để bình luận bên dưới:

Tôi vừa làm thêm một số thử nghiệm. not x is Nonekhông phủ nhận xđầu tiên và sau đó so với None. Trong thực tế, có vẻ như istoán tử có quyền ưu tiên cao hơn khi được sử dụng theo cách đó:

>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False

Do đó, not x is Nonechỉ là, theo ý kiến ​​trung thực của tôi, tốt nhất nên tránh.


Chỉnh sửa thêm:

Tôi vừa mới thử nghiệm thêm và có thể xác nhận rằng nhận xét của bukzor là chính xác. (Ít nhất, tôi không thể chứng minh điều đó bằng cách khác.)

Điều này có nghĩa là if x is not Nonecó kết quả chính xác như if not x is None. Tôi đứng sửa. Cảm ơn bukzor.

Tuy nhiên, câu trả lời của tôi vẫn đứng: Sử dụng thông thườngif x is not None .:]


131

Mã phải được viết để dễ hiểu cho người lập trình trước, và trình biên dịch hoặc trình thông dịch thứ hai. Cấu trúc "không phải" gần giống với tiếng Anh hơn là "không phải".


33

Trăn if x is not Nonehay if not x is None?

TLDR: Trình biên dịch mã byte phân tích cả hai thành x is not None- vì vậy để dễ đọc, hãy sử dụng if x is not None.

Dễ đọc

Chúng tôi sử dụng Python vì chúng tôi coi trọng những thứ như khả năng đọc của con người, khả năng sử dụng và tính chính xác của các mô hình lập trình khác nhau về hiệu suất.

Python tối ưu hóa cho khả năng đọc, đặc biệt là trong bối cảnh này.

Phân tích cú pháp và biên dịch mã byte

Các not ràng buộc yếu hơn is, vì vậy không có sự khác biệt logic ở đây. Xem tài liệu :

Các toán tử isis notkiểm tra nhận dạng đối tượng: x is yđúng khi và chỉ khi x và y là cùng một đối tượng. x is not ymang lại giá trị thật ngược.

Điều is notnày được quy định cụ thể trong ngữ pháp Python như là một cải tiến dễ đọc cho ngôn ngữ:

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

Và do đó, nó là một yếu tố đơn nhất của ngữ pháp là tốt.

Tất nhiên, nó không được phân tích cú pháp giống nhau:

>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"

Nhưng sau đó trình biên dịch byte sẽ thực sự dịch not ... issang is not:

>>> import dis
>>> dis.dis(lambda x, y: x is not y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

Vì vậy, để dễ đọc và sử dụng ngôn ngữ như dự định, vui lòng sử dụng is not.

Để không sử dụng nó là không khôn ngoan.


"Các notràng buộc yếu hơn is, vì vậy không có sự khác biệt logic nào ở đây" - ngoại trừ việc Python không phải thực thi các định danh logic và đại số để giữ (không có lý do nội tại (1 + 2)*3để đánh giá giống như1*3 + 2*3 ). Ở đây rõ ràng Python đang gian lận và tối ưu hóa UNARY_NOTđi.
Alexey

30

Câu trả lời đơn giản hơn mọi người đang làm nó.

Dù sao cũng không có lợi thế về mặt kỹ thuật và "x không phải là y" là những gì mọi người khác sử dụng , điều này làm cho nó trở thành người chiến thắng rõ ràng. Nó không quan trọng rằng nó "trông giống tiếng Anh" hay không; mọi người đều sử dụng nó, điều đó có nghĩa là mọi người dùng Python - ngay cả người dùng Trung Quốc, có ngôn ngữ Python trông không giống ai - sẽ hiểu nó trong nháy mắt, trong đó cú pháp ít phổ biến hơn sẽ cần thêm một vài chu kỳ não để phân tích.

Đừng khác biệt chỉ vì lợi ích của sự khác biệt, ít nhất là trong lĩnh vực này.


11

Các is notnhà điều hành được ưa thích hơn phủ nhận kết quả isvì lý do phong cách. " if x is not None:" đọc giống như tiếng Anh, nhưng "if not x is None: " đòi hỏi sự hiểu biết về quyền ưu tiên của nhà điều hành và không đọc như tiếng Anh.

Nếu có sự khác biệt về hiệu suất, tiền của tôi sẽ được sử dụng is not, nhưng điều này gần như chắc chắn không phải là động lực cho quyết định thích kỹ thuật đó. Nó rõ ràng sẽ phụ thuộc vào việc thực hiện. Vì iskhông thể ghi đè, nên dễ dàng tối ưu hóa mọi phân biệt.


9

Cá nhân, tôi sử dụng

if not (x is None):

được mọi lập trình viên hiểu ngay lập tức mà không mơ hồ, ngay cả những người không phải là chuyên gia về cú pháp Python.


5
Một lập luận công bằng mà tôi đồng ý, nhưng tôi tin rằng lập luận theo phong cách thành ngữ là mạnh mẽ hơn.
clacke

2

if not x is Nonetương tự như các ngôn ngữ lập trình khác, nhưng if x is not Nonechắc chắn nghe rõ hơn (và đúng hơn về mặt ngữ pháp trong tiếng Anh) với tôi.

Điều đó nói rằng có vẻ như đó là một điều ưu tiên đối với tôi.


0

Tôi thích dạng dễ đọc x is not y hơn tôi nghĩ làm thế nào để viết ưu tiên xử lý mã của các toán tử để tạo ra mã dễ đọc hơn nhiều.

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.