Saya menulis sistem keamanan yang menolak akses ke pengguna yang tidak sah.
import sys
print("Hello. Please enter your name:")
name = sys.stdin.readline().strip()
if name == "Kevin" or "Jon" or "Inbar":
print("Access granted.")
else:
print("Access denied.")
Ini memberikan akses ke pengguna resmi seperti yang diharapkan, tetapi juga memungkinkan pengguna yang tidak sah!
Hello. Please enter your name:
Bob
Access granted.
Mengapa ini terjadi? Saya dengan jelas menyatakan untuk hanya memberikan akses jika name
setara dengan Kevin, Jon, atau Inbar. Saya juga mencoba logika yang berlawanan if "Kevin" or "Jon" or "Inbar" == name
, tetapi hasilnya sama.
x or y in z
,x and y in z
,x != y and z
dan beberapa orang lainnya. Meskipun tidak persis sama dengan pertanyaan ini, akar penyebabnya sama untuk semuanya. Hanya ingin menunjukkan hal itu jika ada yang menjawab pertanyaan mereka sebagai duplikat dari ini dan tidak yakin bagaimana itu relevan bagi mereka.Jawaban:
Dalam banyak kasus, Python terlihat dan berperilaku seperti bahasa Inggris alami, tetapi ini adalah salah satu kasus di mana abstraksi tersebut gagal. Orang dapat menggunakan petunjuk konteks untuk menentukan bahwa "Jon" dan "Inbar" adalah objek yang digabungkan dengan kata kerja "sama dengan", tetapi penerjemah Python lebih berpikiran literal.
secara logis setara dengan:
Yang, bagi pengguna Bob, setara dengan:
The
or
Operator memilih argumen pertama dengan positif nilai kebenaran :Dan karena "Jon" memiliki nilai kebenaran positif,
if
blok tersebut dijalankan. Itulah yang menyebabkan "Akses diberikan" untuk dicetak terlepas dari nama yang diberikan.Semua alasan ini juga berlaku untuk ekspresi tersebut
if "Kevin" or "Jon" or "Inbar" == name
. nilai pertama,,"Kevin"
benar, sehinggaif
blok dijalankan.Ada dua cara umum untuk menyusun persyaratan ini dengan benar.
Gunakan beberapa
==
operator untuk secara eksplisit memeriksa setiap nilai:if name == "Kevin" or name == "Jon" or name == "Inbar":
Buat urutan nilai yang valid, dan gunakan
in
operator untuk menguji keanggotaan:if name in {"Kevin", "Jon", "Inbar"}:
Secara umum dari dua yang kedua lebih disukai karena lebih mudah dibaca dan juga lebih cepat:
Bagi yang mungkin menginginkan pembuktian yang
if a == b or c or d or e: ...
memang diurai seperti ini.ast
Modul built-in memberikan jawaban:Sehingga
test
dariif
penampilan pernyataan seperti ini:Seperti yang dapat dilihat, itu operator boolean
or
diterapkan untuk beberapavalues
, yaitu,a == b
danc
,d
, dane
.sumber
("Kevin", "Jon", "Inbar")
daripada satu set{"Kevin", "Jon", "Inbar"}
?a in {b, c, d}
kira-kira dua kali lebih cepata in (b, c, d)
dari mesin saya. Sesuatu untuk dipikirkan jika ini adalah bagian kode yang sangat penting untuk kinerja.frozenset
gantinya, sehingga overhead himpunan konstruksi tidak ada.dis.dis(compile("1 in {1, 2, 3}", '<stdin>', 'eval'))
Masalah teknik sederhana, mari kita bahas lebih jauh.
Tapi, diwarisi dari bahasa C, Python mengevaluasi nilai logis dari bilangan bulat bukan nol sebagai True.
Sekarang, Python membangun logika itu dan membiarkan Anda menggunakan literal logika seperti atau pada bilangan bulat, dan sebagainya
Akhirnya
Cara yang tepat untuk menulisnya adalah:
Demi keamanan, saya juga menyarankan agar Anda tidak memasukkan sandi kode keras.
sumber
Ada 3 kondisi check in
if name == "Kevin" or "Jon" or "Inbar":
dan pernyataan if ini setara dengan
Karena
elif "Jon"
akan selalu benar sehingga akses ke setiap pengguna diberikanLarutan
Anda dapat menggunakan salah satu metode di bawah ini
Cepat
Lambat
Lambat + Kode yang tidak perlu
sumber