如何将Python交互式Shell的代码执行结果存入变量?
Alright, let's solve this problem. You need a function that mimics the Python interactive shell's output when running a string of code—whether it's a simple expression, a print statement, or code that throws an error. Here's a robust implementation that covers all your cases:
import sys import io import traceback import ast def run_code(code): # Save original stdout/stderr to restore later original_stdout = sys.stdout original_stderr = sys.stderr output = "" try: # Set up in-memory streams to capture output stdout_capture = io.StringIO() stderr_capture = io.StringIO() sys.stdout = stdout_capture sys.stderr = stderr_capture # First, try to treat the code as an expression (like the interactive shell does) try: result = eval(code) # Check if the code is an expression (not a statement) and result isn't None # We use AST to distinguish expressions from statements parsed = ast.parse(code) if isinstance(parsed.body[0], ast.Expr) and result is not None: output += str(result) + "\n" except SyntaxError: # If it's not a valid expression, execute it as a statement exec(code) except Exception: # Re-raise non-syntax errors so we can capture their traceback raise # Add any content captured from stdout (e.g., print statements) stdout_content = stdout_capture.getvalue() if stdout_content: output += stdout_content except Exception: # Capture the full traceback if an error occurs stderr_content = stderr_capture.getvalue() if not stderr_content: # Generate traceback manually if stderr wasn't populated output += traceback.format_exc() else: output += stderr_content finally: # Restore original streams to avoid breaking other code sys.stdout = original_stdout sys.stderr = original_stderr # Clean up the capture streams stdout_capture.close() stderr_capture.close() # Remove trailing newline to match your examples (adjust if needed) return output.rstrip("\n")
How this works:
- Output Redirection: We use
io.StringIOto capture bothstdout(whereprintsends text) andstderr(where error messages go). - Expression vs. Statement Handling: The interactive shell automatically prints the result of expressions (like
2+3), but not statements (likex=5). We use Python's AST module to check if the code is an expression, then useevalto get its result and add it to the output. For statements, we useexec. - Error Capture: Any exceptions are caught, and we generate the full traceback just like the interactive shell would, ensuring the error message matches exactly what you'd see in the
pythonshell. - Cleanup: We always restore the original
stdoutandstderrstreams in afinallyblock to prevent messing up other parts of your program.
Test it out:
# Test 1: Simple expression print(run_code("2+3")) # Output: '5' # Test 2: Print statement print(run_code("print('hi')")) # Output: 'hi' # Test 3: Undefined variable error print(run_code("hi")) # Output: # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # NameError: name 'hi' is not defined
This function behaves exactly like the Python interactive shell for all your specified cases, and handles edge cases like assignment statements (which return an empty string) too.
内容的提问来源于stack exchange,提问作者aahnik
相关产品推荐
相关产品推荐

