Banyak jawaban bagus di sini, tetapi tidak ada yang menjelaskan penggunaan eval()
dalam konteksnya globals
dan locals
kwarg, yaitu eval(expression, globals=None, locals=None)
(lihat dokumen untuk di eval
sini ).
Ini dapat digunakan untuk membatasi fungsi yang tersedia melalui eval
fungsi. Misalnya jika Anda memuat juru bahasa python baru locals()
dan globals()
akan sama dan terlihat seperti ini:
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
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]
.
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
Demikian juga semua __builtins__
tersedia.
>>>eval('abs(-1)')
1
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.
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
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.
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
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:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]