Python eval ()

Η μέθοδος eval () αναλύει την έκφραση που μεταβιβάστηκε σε αυτήν τη μέθοδο και εκτελεί την έκφραση python (κωδικός) μέσα στο πρόγραμμα.

Με απλούς όρους, η eval()συνάρτηση εκτελεί τον κώδικα python (ο οποίος περνά ως όρισμα) μέσα στο πρόγραμμα.

Η σύνταξη του eval()είναι:

 eval (έκφραση, σφαιρικά = Κανένα, ντόπιοι = Κανένα)

eval () Παράμετροι

Η eval()συνάρτηση παίρνει τρεις παραμέτρους:

  • έκφραση - η συμβολοσειρά αναλύθηκε και αξιολογήθηκε ως έκφραση Python
  • globals (προαιρετικό) - λεξικό
  • ντόπιοι (προαιρετικά) - ένα αντικείμενο χαρτογράφησης. Το λεξικό είναι ο τυπικός και κοινώς χρησιμοποιούμενος τύπος χαρτογράφησης στο Python.

Η χρήση σφαιρικών και ντόπιων θα συζητηθεί αργότερα σε αυτό το άρθρο.

Επιστροφή τιμή από eval ()

Η μέθοδος eval () επιστρέφει το αποτέλεσμα που αξιολογήθηκε από την έκφραση.

Παράδειγμα 1: Πώς λειτουργεί το eval () στο Python

 x = 1 print(eval('x + 1'))

Παραγωγή

 2

Εδώ, η eval()συνάρτηση αξιολογεί την έκφραση x + 1και printχρησιμοποιείται για την εμφάνιση αυτής της τιμής.

Παράδειγμα 2: Πρακτικό παράδειγμα για την απόδειξη της χρήσης του eval ()

 # Perimeter of Square def calculatePerimeter(l): return 4*l # Area of Square def calculateArea(l): return l*l expression = input("Type a function: ") for l in range(1, 5): if (expression == 'calculatePerimeter(l)'): print("If length is ", l, ", Perimeter = ", eval(expression)) elif (expression == 'calculateArea(l)'): print("If length is ", l, ", Area = ", eval(expression)) else: print('Wrong Function') break

Παραγωγή

 Πληκτρολογήστε μια συνάρτηση: calculArea (l) Εάν το μήκος είναι 1, Περιοχή = 1 Εάν το μήκος είναι 2, Περιοχή = 4 Εάν το μήκος είναι 3, Περιοχή = 9 Εάν το μήκος είναι 4, Περιοχή = 16

Προειδοποιήσεις κατά τη χρήση του eval ()

Σκεφτείτε μια κατάσταση όπου χρησιμοποιείτε ένα σύστημα Unix (macOS, Linux κ.λπ.) και έχετε εισαγάγει τη osλειτουργική μονάδα. Η λειτουργική μονάδα os παρέχει έναν φορητό τρόπο χρήσης λειτουργιών λειτουργικού συστήματος, όπως ανάγνωση ή εγγραφή σε αρχείο.

Αν επιτρέψετε στους χρήστες να εισάγετε μια τιμή, χρησιμοποιώντας eval(input()), ο χρήστης μπορεί να εκδώσει εντολές στο αρχείο αλλαγή ή ακόμα και να διαγράψετε όλα τα αρχεία χρησιμοποιώντας την εντολή: os.system('rm -rf *').

Εάν χρησιμοποιείτε eval(input())τον κωδικό σας, είναι καλή ιδέα να ελέγξετε ποιες μεταβλητές και μεθόδους μπορεί να χρησιμοποιήσει ο χρήστης. Μπορείτε να δείτε ποιες μεταβλητές και μεθόδους είναι διαθέσιμες χρησιμοποιώντας τη μέθοδο dir ().

 from math import * print(eval('dir()'))

Παραγωγή

("__annotations__", "__builtins__", "__cached__", "__doc__", "__file__", "__loader__", "__name__", "__package__", "__spec__", "acos", "acosh", "asin", " asinh "," atan "," atan2 "," atanh "," ceil "," comb "," copysign "," cos "," cosh "," degrees "," dist "," e "," erf " , "erfc", "exp", "expm1", "fabs", "factorial", "floor", "fmod", "frexp", "fsum", "gamma", "gcd", "hypot", " inf ',' isclose ',' isfinite ',' isinf ',' isnan ',' isqrt ',' ldexp ',' lgamma ',' log ',' log10 ',' log1p ','log2 ',' modf ',' nan ',' os ',' perm ',' pi ',' pow ',' prod ',' radians ',' υπόλοιπο ',' sin ',' sinh ',' sqrt ' , "tan", "tanh", "tau", "trunc")

Περιορισμός της χρήσης διαθέσιμων μεθόδων και μεταβλητών στο eval ()

Τις περισσότερες φορές, όλες οι διαθέσιμες μέθοδοι και μεταβλητές που χρησιμοποιούνται στην έκφραση (πρώτη παράμετρος έως eval()) μπορεί να μην χρειάζονται ή ακόμη και να έχουν μια τρύπα ασφαλείας. Ίσως χρειαστεί να περιορίσετε τη χρήση αυτών των μεθόδων και μεταβλητών για eval(). Μπορείτε να το κάνετε μεταφέροντας προαιρετικές παραμέτρους σφαιρικών και τοπικών παραμέτρων (λεξικά) στη eval()συνάρτηση.

1. Όταν παραλείπονται τόσο οι παράμετροι του πλανήτη όσο και των τοπικών

Εάν παραλείπονται και οι δύο παράμετροι (όπως στα προηγούμενα παραδείγματα), η έκφραση εκτελείται στο τρέχον πεδίο. Μπορείτε να ελέγξετε τις διαθέσιμες μεταβλητές και μεθόδους χρησιμοποιώντας τον ακόλουθο κώδικα:

 print(eval('dir()')

2. Παράμετρος διέλευσης σφαιρών. Η παράμετρος locals παραλείπεται

Οι παράμετροι σφαιρικών και τοπικών (λεξικά) χρησιμοποιούνται για καθολικές και τοπικές μεταβλητές αντίστοιχα. Εάν το λεξικό των ντόπιων παραλειφθεί, προεπιλογή στο λεξικό globals. Δηλαδή, τα σφαιρικά θα χρησιμοποιηθούν τόσο για παγκόσμιες όσο και για τοπικές μεταβλητές.

Σημείωση: Μπορείτε να ελέγξετε το τρέχον παγκόσμιο και τοπικό λεξικό στο Python χρησιμοποιώντας ενσωματωμένες μεθόδους globals () και locals () αντίστοιχα.

Παράδειγμα 3: Μετάδοση κενού λεξικού ως παράμετρος σφαιρών

 from math import * print(eval('dir()', ())) # The code will raise an exception print(eval('sqrt(25)', ()))

Παραγωγή

 ('__builtins__') Ανίχνευση (τελευταία τελευταία κλήση): Αρχείο "", γραμμή 5, σε εκτύπωση (eval ('sqrt (25)', ())) Αρχείο "", γραμμή 1, στο NameError: name 'sqrt' δεν έχει προσδιοριστεί

Εάν περάσετε ένα κενό λεξικό ως σφαιρικά, μόνο τα __builtins__διαθέσιμα είναι expression(πρώτη παράμετρος στο eval()).

Παρόλο που έχουμε εισαγάγει την mathενότητα στο παραπάνω πρόγραμμα, η έκφραση δεν μπορεί να έχει πρόσβαση σε λειτουργίες που παρέχονται από τη μαθηματική ενότητα.

Παράδειγμα 4: Διάθεση ορισμένων μεθόδων

 from math import * print(eval('dir()', ('sqrt': sqrt, 'pow': pow)))

Παραγωγή

 ('__builtins__', 'pow', 'sqrt')

Εδώ, η έκφραση μπορεί να χρησιμοποιήσει μόνο το sqrt()και τις pow()μεθόδους μαζί με __builtins__.

Είναι επίσης δυνατό να αλλάξετε το όνομα της διαθέσιμης μεθόδου για την έκφραση ως προς την επιθυμία σας:

 from math import * names = ('square_root': sqrt, 'power': pow) print(eval('dir()', names)) # Using square_root in Expression print(eval('square_root(9)', names))

Παραγωγή

 ('__builtins__', 'power', 'square_root') 3.0

Στο παραπάνω πρόγραμμα, square_root()υπολογίζει τη χρήση της τετραγωνικής ρίζας sqrt(). Ωστόσο, η προσπάθεια sqrt()απευθείας χρήσης θα προκαλέσει σφάλμα.

Παράδειγμα 5: Περιορισμός της χρήσης ενσωματωμένων

Μπορείτε να περιορίσετε τη χρήση της __builtins__έκφρασης ως εξής:

 eval(expression, ('__builtins__': None))

3. Περνώντας λεξικό σε παγκόσμια κλίμακα και ντόπιους

Μπορείτε να διαθέσετε τις απαραίτητες συναρτήσεις και μεταβλητές για χρήση, περνώντας το λεξικό των ντόπιων. Για παράδειγμα:

 from math import * a = 169 print(eval('sqrt(a)', ('__builtins__': None), ('a': a, 'sqrt': sqrt)))

Παραγωγή

 13.0

Σε αυτό το πρόγραμμα, η έκφραση μπορεί να έχει μόνο sqrt()μέθοδο και μεταβλητή. Όλες οι άλλες μέθοδοι και μεταβλητές δεν είναι διαθέσιμες.

Ο περιορισμός της χρήσης eval()με τη μετάδοση σφαιρικών και τοπικών λεξικών θα κάνει τον κώδικά σας ασφαλή ιδιαίτερα όταν χρησιμοποιείτε είσοδο που παρέχεται από τον χρήστη στη eval()μέθοδο.

Σημείωση: Μερικές φορές, eval()δεν είναι ασφαλές ακόμη και με περιορισμένα ονόματα. Όταν ένα αντικείμενο και οι μέθοδοι του γίνουν προσβάσιμες, σχεδόν οτιδήποτε μπορεί να γίνει. Ο μόνος ασφαλής τρόπος είναι με την επικύρωση της εισόδου χρήστη.

ενδιαφέροντα άρθρα...