Dalam buku yang saya baca di Python, ia terus menggunakan kode eval(input('blah'))
Saya membaca dokumentasi, dan saya memahaminya, tetapi saya masih tidak melihat bagaimana itu mengubah input()
fungsinya.
Apa fungsinya? Bisakah seseorang menjelaskan?
Jawaban:
Fungsi eval memungkinkan program Python menjalankan kode Python di dalam dirinya sendiri.
contoh eval (shell interaktif):
sumber
eval()
juga dapat digunakan untuk mengeksekusi kode yang sangat dinamis, tetapi Anda harus membuat diri Anda sepenuhnya sadar akan risiko keamanan dan kinerja sebelum menggunakannya.eval
, juga tidak bisa melakukan apa yang dilakukannyaeval
.eval
, selain tidak aman, tidak dapat menjalankan seluruh program seperti yang dilakukan codepad karena hanya dapat mengevaluasi satu ekspresi.eval()
menafsirkan string sebagai kode. Alasan mengapa begitu banyak orang telah memperingatkan Anda tentang penggunaan ini adalah karena pengguna dapat menggunakan ini sebagai opsi untuk menjalankan kode di komputer. Jika Anda telaheval(input())
danos
mengimpor, seseorang dapat mengetikinput()
os.system('rm -R *')
mana akan menghapus semua file Anda di direktori home Anda. (Dengan asumsi Anda memiliki sistem unix). Menggunakaneval()
adalah lubang keamanan. Jika Anda perlu mengonversi string ke format lain, coba gunakan hal-hal yang melakukannya, sepertiint()
.sumber
eval
denganinput()
adalah lubang keamanan. Jangan memasukkaninput()
pernyataan eval dan Anda akan baik-baik saja.eval
juga masalah keamanan dalam banyak kasus.input
biasanya mengambil datanya dari konsol, pengguna dapat keluar dari program dan mengetikkanrm -R *
...Banyak jawaban bagus di sini, tetapi tidak ada yang menjelaskan penggunaan
eval()
dalam konteksnyaglobals
danlocals
kwarg, yaitueval(expression, globals=None, locals=None)
(lihat dokumen untuk dieval
sini ).Ini dapat digunakan untuk membatasi fungsi yang tersedia melalui
eval
fungsi. Misalnya jika Anda memuat juru bahasa python barulocals()
danglobals()
akan sama dan terlihat seperti ini:Tentu saja ada fungsi-fungsi di dalam
builtins
modul yang dapat merusak sistem secara signifikan. Tetapi dimungkinkan untuk memblokir apa saja dan segala sesuatu yang tidak kita inginkan tersedia. Mari kita ambil contoh. Katakanlah kita ingin membuat daftar untuk merepresentasikan domain dari inti yang tersedia pada suatu sistem. Bagi saya, saya memiliki 8 core sehingga saya ingin daftar[1, 8]
.Demikian juga semua
__builtins__
tersedia.Baik. Jadi di sana kita melihat satu fungsi yang kita inginkan terpapar dan contoh dari satu (dari banyak yang bisa menjadi jauh lebih kompleks) metode yang kita tidak ingin terpapar. Jadi mari kita blokir semuanya.
Kami telah secara efektif memblokir semua
__builtins__
fungsi dan dengan demikian membawa tingkat perlindungan ke sistem kami. Pada titik ini kita dapat mulai menambahkan kembali fungsi yang ingin kita tampilkan.Sekarang kami memiliki
cpu_count
fungsi yang tersedia sementara masih memblokir semua yang tidak kami inginkan. Menurut pendapat saya, ini sangat kuat dan jelas dari ruang lingkup jawaban lain, bukan implementasi umum. Ada banyak kegunaan untuk sesuatu seperti ini dan selama itu ditangani dengan benar, saya pribadi merasaeval
dapat digunakan dengan aman untuk nilai yang besar.NB
Hal lain yang keren tentang ini
kwargs
adalah Anda dapat mulai menggunakan singkatan untuk kode Anda. Katakanlah Anda menggunakan eval sebagai bagian dari pipeline untuk mengeksekusi beberapa teks yang diimpor. Teks tidak perlu memiliki kode yang tepat, dapat mengikuti beberapa format file templat, dan masih menjalankan apa pun yang Anda inginkan. Sebagai contoh:sumber
Dalam Python 2.x
input(...)
setara denganeval(raw_input(...))
, dalam Python 3.xraw_input
diganti namanyainput
, yang saya curiga menyebabkan kebingungan Anda (Anda mungkin melihat dokumentasi untukinput
Python 2.x). Selain itu,eval(input(...))
akan berfungsi dengan baik di Python 3.x, tetapi akan menaikkanTypeError
dalam Python 2.Dalam hal
eval
ini digunakan untuk memaksa string yang dikembalikan dariinput
menjadi ekspresi dan ditafsirkan. Umumnya ini dianggap praktik buruk.sumber
input
berarti apa yangraw_input
dilakukan dalam 2.x.Mungkin contoh yang menyesatkan dari membaca garis dan menafsirkannya.
Coba
eval(input())
dan ketik"1+1"
- ini harus dicetak2
. Eval mengevaluasi ekspresi.sumber
eval()
mengevaluasi string yang diteruskan sebagai ekspresi Python dan mengembalikan hasilnya. Misalnya,eval("1 + 1")
menafsirkan dan mengeksekusi ekspresi"1 + 1"
dan mengembalikan hasilnya (2).Salah satu alasan Anda mungkin bingung adalah karena kode yang Anda kutip melibatkan tingkat tipuan. Panggilan fungsi bagian dalam (input) dijalankan terlebih dahulu sehingga pengguna melihat prompt "bla". Mari kita bayangkan mereka merespons dengan "1 + 1" (tanda kutip ditambahkan untuk kejelasan, jangan mengetiknya saat menjalankan program Anda), fungsi input mengembalikan string itu, yang kemudian diteruskan ke fungsi luar (eval) yang mengartikan string dan mengembalikan hasilnya (2).
Baca lebih lanjut tentang eval di sini .
sumber
eval()
, seperti namanya, mengevaluasi argumen yang diteruskan.raw_input()
sekaranginput()
dalam versi python 3.x. Jadi contoh yang paling umum ditemukan untuk penggunaaneval()
adalah penggunaannya untuk menyediakan fungsionalitas ituinput()
disediakan dalam versi 2.x dari python. raw_input mengembalikan data yang dimasukkan pengguna sebagai string, sementara input mengevaluasi nilai data yang dimasukkan dan mengembalikannya.eval(input("bla bla"))
dengan demikian mereplikasi fungsi dariinput()
dalam 2.x, yaitu mengevaluasi data yang dimasukkan pengguna.Singkatnya:
eval()
mengevaluasi argumen yang diterima dan karenanyaeval('1 + 1')
mengembalikan 2.sumber
Salah satu aplikasi yang berguna
eval()
adalah untuk mengevaluasi ekspresi python dari string. Misalnya memuat dari representasi string file kamus:Bacakan sebagai variabel dan edit:
Keluaran:
sumber
eval
?Saya terlambat menjawab pertanyaan ini, tetapi, sepertinya tidak ada yang memberikan jawaban yang jelas untuk pertanyaan itu.
Jika pengguna memasukkan nilai numerik,
input()
akan mengembalikan string.Jadi,
eval()
akan mengevaluasi nilai yang dikembalikan (atau ekspresi) yang merupakan string dan return integer / float.Tentu saja ini adalah praktik yang buruk.
int()
ataufloat()
harus digunakan sebagai gantieval()
dalam hal ini.sumber
Opsi lain jika Anda ingin membatasi string evaluasi menjadi literal sederhana adalah menggunakan
ast.literal_eval()
. Beberapa contoh:Dari dokumen :
Adapun alasannya sangat terbatas, dari milis :
sumber
ast.literal_eval
tidak mendukung operator, bertentangan dengan'1+1'
contoh Anda . Meskipun demikian itu memang mendukung daftar, angka, string dll, dan merupakan alternatif yang baik untukeval
kasus penggunaan umum .