如何防止向含eval函数的变量输入非法字符及解决未定义报错?
Hey there, let's break down your problem and fix it step by step—eval can be tricky and unsafe if not handled properly, so we'll cover both the security aspect and the error you're seeing.
Why Your Current Code Causes Issues
First, let's unpack what's happening when you input g: your code runs eval(input(...)), which tries to evaluate the string g as Python code. Since g isn't defined anywhere in your script, you get that NameError. Beyond that, using eval with raw user input is a huge security risk—someone could input malicious code (like commands to delete files) that eval would execute directly.
Solution 1: Ditch eval Entirely (Recommended)
The safest and simplest fix is to stop using eval altogether. Since you're asking for an angle to compute sin(radians(angle)), just have the user input a number, parse it safely, and do the calculation yourself.
Here's a rewritten version of your code:
import math while True: user_input = input("Input your angle in degrees: ") try: # Try converting input to a float (handles integers, decimals, even scientific notation) angle = float(user_input) # Calculate the sine value directly sine_value = math.sin(math.radians(angle)) print(f"Valid input! The sine value is: {sine_value}") break except ValueError: # Catch non-numeric inputs and prompt again print("This is not a valid input—please enter a number (integer or decimal).")
- When someone inputs
g,float(g)throws aValueError, which we catch to show a friendly error message. - No
evalmeans no security risks, and no unexpectedNameErrors from undefined variables.
Solution 2: Safe Expression Evaluation (If You Need Flexibility)
If you want to let users input simple math expressions (like 90 + 30 or pi/2), you can still avoid full eval risks by filtering input and restricting the namespace eval can access.
First, use a regex to block any characters that aren't part of valid numeric expressions. Then, use eval with a locked-down namespace so users can't access dangerous functions:
import math import re # Regex to allow only numbers, basic operators, parentheses, decimals, and scientific notation (e/E) allowed_chars = re.compile(r'^[\d+\-*/().eE]+$') while True: user_input = input("Input an angle (or simple math expression) in degrees: ") # First, check if input contains only allowed characters if not allowed_chars.match(user_input): print("Invalid input! Only numbers, +, -, *, /, (, ), ., e/E are allowed.") continue try: # Run eval with a restricted namespace: no built-in functions, only explicit math utilities angle = eval( user_input, {"__builtins__": None}, # Lock global namespace to block dangerous functions {"pi": math.pi} # Allow specific math variables if needed ) # Verify the result is a number if isinstance(angle, (int, float, complex)): sine_value = math.sin(math.radians(angle)) print(f"Valid input! The sine value is: {sine_value}") break else: print("This is not a valid input—please enter a numeric value or expression.") except (SyntaxError, NameError, TypeError, ZeroDivisionError) as e: print(f"Invalid input: {str(e)}. Please try again.")
- This blocks inputs like
g(sincegisn't in the allowed character set) or malicious code (since__builtins__is disabled). - If someone tries to input an undefined variable, the regex catches it before
evalruns, or theNameErroris caught and handled.
Key Takeaways
- Avoid
evalwith user input whenever possible: It's the biggest source of security risks and unexpected errors. - Validate input upfront: Use type conversion (like
float()) or regex to ensure users only enter what you expect. - If you must use
eval, lock it down: Restrict the namespace to only the functions/variables users need, and never let them access built-in functions that can execute code.
内容的提问来源于stack exchange,提问作者Alexander Tawil

