Python跨目录导入文件:批量测试学生提交代码的实现咨询
Alright, let's tackle your problem of cross-directory imports and batch testing student submissions. Here's a step-by-step solution that's clean, maintainable, and handles edge cases like missing functions or invalid code:
First, let's align on your setup to ensure we're solving the right problem:
- Your working script:
D:\test_math.py - Target submissions folder:
C:\user\desktop\submissions - Inside
submissions: Folders likestudent1,student2, each containing amy_math.pywithadd(),sub(),mul()functions.
Instead of modifying Python's default sys.path (which can cause conflicts if multiple modules share the same name), we'll use importlib.util to load each student's my_math.py directly from its directory. This is the most robust approach for this scenario.
We'll:
- Traverse all student directories in
submissions - Load each
my_math.pyas an independent module - Run standardized test cases on the module's functions
- Capture and report results (including errors like missing functions or incorrect outputs)
Drop this complete code into your D:\test_math.py:
import os import importlib.util def test_math_module(module, student_name): """Test the add, sub, mul functions of a student's my_math module.""" test_results = { "student": student_name, "passed": 0, "failed": 0, "errors": [] } # Test add function try: assert module.add(2, 3) == 5, "Expected 5 for add(2,3)" test_results["passed"] += 1 except AttributeError: test_results["errors"].append("Missing add() function") except AssertionError as e: test_results["failed"] += 1 test_results["errors"].append(str(e)) except Exception as e: test_results["errors"].append(f"add() threw unexpected error: {str(e)}") # Test sub function try: assert module.sub(5, 2) == 3, "Expected 3 for sub(5,2)" test_results["passed"] += 1 except AttributeError: test_results["errors"].append("Missing sub() function") except AssertionError as e: test_results["failed"] += 1 test_results["errors"].append(str(e)) except Exception as e: test_results["errors"].append(f"sub() threw unexpected error: {str(e)}") # Test mul function try: assert module.mul(4, 5) == 20, "Expected 20 for mul(4,5)" test_results["passed"] += 1 except AttributeError: test_results["errors"].append("Missing mul() function") except AssertionError as e: test_results["failed"] += 1 test_results["errors"].append(str(e)) except Exception as e: test_results["errors"].append(f"mul() threw unexpected error: {str(e)}") return test_results def main(): # Define the root submissions directory (raw string avoids Windows path escape issues) submissions_dir = r'C:\user\desktop\submissions' # Validate the submissions directory exists if not os.path.isdir(submissions_dir): print(f"Error: Submissions directory {submissions_dir} does not exist.") return # Traverse all student directories for student_folder in os.listdir(submissions_dir): student_path = os.path.join(submissions_dir, student_folder) # Skip non-directory items (in case files exist directly in submissions) if not os.path.isdir(student_path): continue # Path to the student's my_math.py my_math_path = os.path.join(student_path, 'my_math.py') if not os.path.isfile(my_math_path): print(f"Warning: {student_folder} has no my_math.py file. Skipping.") continue # Load the module directly from the file path spec = importlib.util.spec_from_file_location(f"{student_folder}_my_math", my_math_path) if spec is None or spec.loader is None: print(f"Error: Could not load spec for {my_math_path}. Skipping.") continue my_math_module = importlib.util.module_from_spec(spec) try: spec.loader.exec_module(my_math_module) except Exception as e: print(f"Error: Failed to execute {my_math_path}: {str(e)}") continue # Run tests and get results results = test_math_module(my_math_module, student_folder) # Print formatted results for the student print(f"\n=== Results for {results['student']} ===") print(f"Passed: {results['passed']}/3") print(f"Failed: {results['failed']}/3") if results['errors']: print("Errors:") for error in results['errors']: print(f"- {error}") if __name__ == "__main__": main()
- Safe Path Handling: We use
os.path.join()to build paths that work across Windows, macOS, and Linux, avoiding issues with backslashes/forward slashes. - Isolated Module Loading:
importlib.utillets us load each student's module without adding their directory to Python's global path, preventing naming conflicts between submissions. - Comprehensive Error Handling: We catch missing functions, incorrect outputs, and unexpected crashes to give you clear, actionable feedback for each student.
- Automated Batch Processing: The script automatically iterates over all student folders, so you don't have to manually update paths for each new submission.
- Save the code above as
D:\test_math.py - Double-check the
submissions_dirpath inmain()matches your actual submissions folder location - Run the script via command line:
python D:\test_math.py
You'll get a detailed report for each student showing test pass/fail counts and any errors encountered.
内容的提问来源于stack exchange,提问作者Sreekar Mouli

