σφάλμα input() - NameError: το όνομα '...' δεν έχει οριστεί

Λαμβάνω ένα σφάλμα όταν προσπαθώ να εκτελέσω αυτό το απλό σενάριο python:

input_variable = input ("Enter your name: ")
print ("your name is" + input_variable)

Ας πούμε ότι πληκτρολογώ το "dude", το σφάλμα που λαμβάνω είναι:

line 1, in <module>
input_variable = input ("Enter your name: ")
File "<string>", line 1, in <module>
NameError: name 'dude' is not defined

Τρέχω Mac OS X 10.9.1 και χρησιμοποιώ την εφαρμογή Python Launcher που συνοδεύει την εγκατάσταση της python 3.3 για να τρέξω το σενάριο.

Επεξεργασία: Συνειδητοποίησα ότι με κάποιο τρόπο τρέχω αυτά τα σενάρια με την έκδοση 2.7. Υποθέτω ότι το πραγματικό ερώτημα είναι πώς μπορώ να τρέξω τα σενάριά μου με την έκδοση 3.3; Σκέφτηκα ότι αν σύρω και αφήσω τα σενάριά μου πάνω στην εφαρμογή Python Launcher που βρίσκεται μέσα στο φάκελο Python 3.3 στο φάκελο εφαρμογών μου, θα ξεκινούσε τα σενάριά μου χρησιμοποιώντας την έκδοση 3.3. Υποθέτω ότι αυτή η μέθοδος εξακολουθεί να εκκινεί τα σενάρια με την έκδοση 2.7. Πώς μπορώ λοιπόν να χρησιμοποιήσω την 3.3;

TL;DR

Η συνάρτηση input στην Python 2.7, αξιολογεί οτιδήποτε εισάγετε, ως έκφραση Python. Αν θέλετε απλά να διαβάσετε συμβολοσειρές, τότε χρησιμοποιήστε τη συνάρτηση raw_input στην Python 2.7, η οποία δεν θα αξιολογήσει τις συμβολοσειρές που διαβάζετε.

Αν χρησιμοποιείτε την Python 3.x, η raw_input έχει μετονομαστεί σε input. Παραθέτω τις Σημειώσεις έκδοσης της Python 3.0,

Η raw_input() μετονομάστηκε σε input(). Δηλαδή, η νέα συνάρτηση input() διαβάζει μια γραμμή από την sys.stdin και την επιστρέφει με την τελευταία νέα γραμμή απογυμνωμένη. Προκαλεί EOFError αν η είσοδος τερματιστεί πρόωρα. Για να έχετε την παλιά συμπεριφορά της input(), χρησιμοποιήστε την eval(input())


Στην Python 2.7, υπάρχουν δύο συναρτήσεις που μπορούν να χρησιμοποιηθούν για να δεχτούν εισόδους χρήστη. Η μία είναι η input και η άλλη η raw_input. Μπορείτε να σκεφτείτε τη σχέση μεταξύ τους ως εξής

input = eval(raw_input)

Σκεφτείτε το ακόλουθο κομμάτι κώδικα για να το καταλάβετε καλύτερα

>>> dude = "thefourtheye"
>>> input_variable = input("Enter your name: ")
Enter your name: dude
>>> input_variable
'thefourtheye'

Το input δέχεται μια συμβολοσειρά από τον χρήστη και αξιολογεί τη συμβολοσειρά στο τρέχον πλαίσιο της Python. Όταν πληκτρολογώ dude ως είσοδο, διαπιστώνει ότι το dude είναι συνδεδεμένο με την τιμή thefourtheye και έτσι το αποτέλεσμα της αξιολόγησης γίνεται thefourtheye και αυτό ανατίθεται στην input_variable.

Αν εισάγω κάτι άλλο που δεν υπάρχει στο τρέχον πλαίσιο της python, θα αποτύχει θα δώσει το NameError.

>>> input("Enter your name: ")
Enter your name: dummy
Traceback (most recent call last):
  File "<input>", line 1, in 
  File "", line 1, in 
NameError: name 'dummy' is not defined

Προβληματισμοί ασφαλείας με την Python 2.7's input:

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

os.remove("/etc/hosts")

αυτό θα αξιολογηθεί ως έκφραση κλήσης συνάρτησης από την python και θα εκτελεστεί. Αν εκτελείτε την Python με αυξημένα προνόμια, το αρχείο /etc/hosts θα διαγραφεί. Βλέπετε πόσο επικίνδυνο μπορεί να είναι;

Για να το δείξουμε αυτό, ας προσπαθήσουμε να εκτελέσουμε ξανά τη συνάρτηση input.

>>> dude = "thefourtheye"
>>> input("Enter your name: ")
Enter your name: input("Enter your name again: ")
Enter your name again: dude

Τώρα, όταν εκτελείται η input("Enter your name: "), περιμένει την είσοδο του χρήστη και η είσοδος του χρήστη είναι μια έγκυρη κλήση συνάρτησης Python και έτσι αυτή επίσης καλείται. Αυτός είναι ο λόγος για τον οποίο βλέπουμε ξανά την προτροπή Enter your name again:.

Έτσι, είναι καλύτερα να χρησιμοποιήσετε τη συνάρτηση raw_input, όπως αυτή

input_variable = raw_input("Enter your name: ")

Αν χρειάζεται να μετατρέψετε το αποτέλεσμα σε κάποιον άλλο τύπο, τότε μπορείτε να χρησιμοποιήσετε τις κατάλληλες συναρτήσεις για να μετατρέψετε το αλφαριθμητικό που επιστρέφει η raw_input. Για παράδειγμα, για να διαβάσετε τις εισόδους ως ακέραιους αριθμούς, χρησιμοποιήστε τη συνάρτηση int, όπως φαίνεται στην αυτή την απάντηση.

Στην python 3.x, υπάρχει μόνο μία συνάρτηση για να λαμβάνετε τις εισόδους του χρήστη και αυτή ονομάζεται input, η οποία είναι ισοδύναμη με την raw_input της Python 2.7's.

Σχόλια (0)

Εκτελείτε Python 2, όχι Python 3. Για να λειτουργήσει αυτό στην Python 2, χρησιμοποιήστε την raw_input.

input_variable = raw_input ("Enter your name: ")
print ("your name is" + input_variable)
Σχόλια (0)

Εφόσον γράφετε για την Python 3.x, θα θέλετε να ξεκινήσετε το σενάριό σας με:

#!/usr/bin/env python3

Εάν χρησιμοποιείτε:

#!/usr/bin/env python

Θα προεπιλεγεί η Python 2.x. Αυτά μπαίνουν στην πρώτη γραμμή του σεναρίου σας, αν δεν υπάρχει τίποτα που να ξεκινάει με #! (ή αλλιώς το shebang).

Αν τα σενάριά σας ξεκινούν μόνο με:

#! python

Τότε μπορείτε να το αλλάξετε σε:

#! python3

Αν και αυτή η συντομότερη μορφοποίηση αναγνωρίζεται μόνο από λίγα προγράμματα, όπως ο εκτοξευτής, οπότε δεν είναι η καλύτερη επιλογή.

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

Σχόλια (0)