Python `jika x tidak ada` atau` jika tidak x tidak ada`?

747

Saya selalu memikirkan if not x is Noneversi yang lebih jelas, tetapi panduan gaya Google dan PEP-8 keduanya digunakan if x is not None. Apakah ada perbedaan kinerja kecil (saya berasumsi tidak), dan adakah kasus di mana yang satu benar-benar tidak cocok (menjadikan yang lain pemenang yang jelas untuk konvensi saya)? *

* Saya merujuk pada singleton mana pun, bukan hanya None.

... untuk membandingkan lajang seperti Tidak Ada. Gunakan atau tidak.

orokusaki
sumber
8
is notadalah operator di dalamnya sendiri. Seperti !=. Jika Anda suka not x is Nonemaka Anda juga harus memilih not a == blebih a != b.
Tomasz Gandor
@ ThomaszGandor Saya tidak lagi memiliki pendapat tentang not x is None(jawaban di sini meyakinkan saya) - namun, perlu dicatat bahwa itu not a == badalah gaya yang disukai dalam Python, dibandingkan dengan a != b.
orokusaki
4
@orokusaki not a == bbenar-benar gaya yang disukai? Saya belum pernah melihatnya seperti itu dan di mana-mana saya melihat orang-orang menggunakannya !=.
Mike - SMT
2
@orokusaki Dalam Python jumlah pembacaan sehingga merupakan gaya pilihan untuk menggunakan satu operator !=bukan dua operator not, ==.
Jeyekomon

Jawaban:

995

Tidak ada perbedaan kinerja, karena mereka mengkompilasi ke bytecode yang sama:

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

Secara gaya, saya mencoba menghindari not x is y. Meskipun kompiler akan selalu memperlakukannya sebagai not (x is y), pembaca manusia mungkin salah memahami konstruk sebagai (not x) is y. Jika saya menulis x is not ymaka tidak ada ambiguitas.

Daniel Stutzbach
sumber
103
Kecuali pembaca manusia yang sama mengira begitu x is (not y). Tapi saya cenderung setuju dengan Anda untuk alasan Anda yang lain.
Etaoin
24
selain itu "tidak" kurang ambigu dalam konteks ini "jika a tidak ada dan b tidak ada:" vs "jika tidak a tidak ada dan b tidak ada:"
Gordon Wrigley
45
operator harus "tidak"
kacang
217

Panduan gaya Google dan Python adalah praktik terbaik:

if x is not None:
    # Do something about x

Penggunaan not xdapat menyebabkan hasil yang tidak diinginkan.

Lihat di bawah:

>>> 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

Anda mungkin tertarik untuk melihat literal apa yang dievaluasi Trueatau Falsedengan Python:


Edit untuk komentar di bawah ini:

Saya hanya melakukan beberapa pengujian lagi. not x is Nonetidak meniadakan xterlebih dahulu dan kemudian dibandingkan dengan None. Bahkan, tampaknya isoperator memiliki prioritas lebih tinggi ketika digunakan seperti itu:

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

Karena itu, not x is Noneadil, menurut pendapat jujur ​​saya, sebaiknya dihindari.


Lebih banyak edit:

Saya hanya melakukan lebih banyak pengujian dan dapat mengonfirmasi bahwa komentar bukzor benar. (Setidaknya, saya tidak bisa membuktikannya sebaliknya.)

Ini berarti if x is not Nonememiliki hasil yang tepat sebagai if not x is None. Saya berdiri dikoreksi. Terima kasih bukzor.

Namun, jawaban saya tetap: Gunakan yang konvensionalif x is not None .:]

Xavier Ho
sumber
131

Kode harus ditulis agar dapat dimengerti oleh programmer terlebih dahulu, dan compiler atau interpreter kedua. Konstruk "tidak" menyerupai bahasa Inggris lebih dekat daripada "tidak".

Mark tebusan
sumber
33

Python if x is not Noneatau if not x is None?

TLDR: Compiler bytecode mem-parsing mereka berdua x is not None- jadi demi keterbacaan, gunakan if x is not None.

Keterbacaan

Kami menggunakan Python karena kami menghargai hal-hal seperti keterbacaan manusia, kemampuan penggunaan, dan kebenaran berbagai paradigma pemrograman dibandingkan kinerja.

Python mengoptimalkan keterbacaan, terutama dalam konteks ini.

Parsing dan Kompilasi Bytecode

The not mengikat lebih lemah dari is, sehingga tidak ada perbedaan logis di sini. Lihat dokumentasi :

Operator isdan is notuji untuk identitas objek: x is ybenar jika dan hanya jika x dan y adalah objek yang sama. x is not ymenghasilkan nilai kebenaran terbalik.

Secara is notkhusus disediakan dalam tata bahasa Python sebagai peningkatan keterbacaan untuk bahasa:

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

Dan itu juga merupakan elemen kesatuan dari tata bahasa juga.

Tentu saja, tidak diuraikan sama:

>>> 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())]))"

Tetapi kemudian byte compiler akan menerjemahkan not ... iske 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

Jadi demi keterbacaan dan penggunaan bahasa seperti yang dimaksudkan, silakan gunakan is not.

Untuk tidak menggunakannya itu tidak bijaksana.

Aaron Hall
sumber
" notIkatan lebih lemah daripada is, jadi tidak ada perbedaan logis di sini" - kecuali bahwa Python tidak harus menegakkan identitas logis dan aljabar untuk dipegang (tidak ada alasan intrinsik untuk (1 + 2)*3mengevaluasi sama seperti 1*3 + 2*3). Di sini rupanya Python curang dan mengoptimalkan UNARY_NOT.
Alexey
30

Jawabannya lebih sederhana daripada orang membuatnya.

Tidak ada keuntungan teknis, dan "x bukan y" adalah apa yang digunakan semua orang , yang membuatnya menjadi pemenang yang jelas. Tidak masalah bahwa itu "lebih mirip bahasa Inggris" atau tidak; semua orang menggunakannya, yang berarti setiap pengguna Python - bahkan pengguna Cina, yang bahasa Python-nya tidak mirip - akan memahaminya sekilas, di mana sintaksis yang sedikit kurang umum akan membutuhkan beberapa siklus otak ekstra untuk diuraikan.

Jangan berbeda hanya demi menjadi berbeda, setidaknya di bidang ini.

Glenn Maynard
sumber
11

The is notOperator lebih disukai daripada meniadakan hasil isuntuk alasan gaya. " if x is not None:" berbunyi seperti bahasa Inggris, tetapi " if not x is None:" memerlukan pemahaman tentang prioritas operator dan tidak "" dibaca seperti bahasa Inggris.

Jika ada perbedaan kinerja uang saya aktif is not, tetapi ini hampir pasti bukan motivasi untuk keputusan untuk memilih teknik itu. Jelas akan tergantung pada implementasi. Karena istidak dapat ditiadakan, seharusnya mudah untuk mengoptimalkan perbedaan apa pun.

Mike Graham
sumber
9

Secara pribadi, saya menggunakan

if not (x is None):

yang dipahami segera tanpa ambiguitas oleh setiap programmer, bahkan mereka yang tidak ahli dalam sintaksis Python.

MikeTeX
sumber
5
Argumen yang adil yang saya setujui, tetapi saya percaya argumen mengikuti gaya idiomatik lebih kuat.
clacke
2

if not x is Nonelebih mirip dengan bahasa pemrograman lain, tetapi if x is not Nonejelas terdengar lebih jelas (dan lebih tepat secara gramatikal dalam bahasa Inggris) bagi saya.

Yang mengatakan sepertinya itu lebih merupakan hal preferensi bagiku.

Davy8
sumber
0

Saya lebih suka bentuk yang lebih mudah dibaca x is not y daripada yang saya pikirkan bagaimana akhirnya menulis kode penanganan prioritas operator untuk menghasilkan kode yang lebih mudah dibaca.

stefanogreg
sumber