Sys Module: System-Specific Parameters and Functions
TL;DR
The sys module provides access to interpreter variables like sys.argv (command-line arguments), sys.path (module search paths), sys.version, sys.exit(), and functions for interacting with the Python runtime environment.
Interesting!
The sys module gives you access to the same command-line arguments that started your Python script through sys.argv, where argv[0] is always the script name and argv[1:] contains the actual arguments - just like the traditional argc/argv pattern from C programming.
Command-Line Arguments
python code snippet start
import sys
# sys.argv contains command-line arguments
# For script: python myscript.py arg1 arg2 --flag
print(f"Script name: {sys.argv[0]}")
print(f"All arguments: {sys.argv}")
print(f"Argument count: {len(sys.argv)}")
# Process arguments
if len(sys.argv) > 1:
for i, arg in enumerate(sys.argv[1:], 1):
print(f"Argument {i}: {arg}")
else:
print("No arguments provided")
# Simple argument parsing
def parse_simple_args():
"""Simple command-line argument parsing"""
args = sys.argv[1:] # Skip script name
flags = []
params = []
for arg in args:
if arg.startswith('--'):
flags.append(arg[2:]) # Remove --
elif arg.startswith('-'):
flags.append(arg[1:]) # Remove -
else:
params.append(arg)
return flags, params
# Example usage
# python script.py file1.txt file2.txt --verbose -d
flags, params = parse_simple_args()
print(f"Flags: {flags}") # ['verbose', 'd']
print(f"Parameters: {params}") # ['file1.txt', 'file2.txt']
python code snippet end
Python Version and Implementation
python code snippet start
import sys
# Python version information
print(f"Python version: {sys.version}")
print(f"Version info: {sys.version_info}")
print(f"Major version: {sys.version_info.major}")
print(f"Minor version: {sys.version_info.minor}")
print(f"Micro version: {sys.version_info.micro}")
# Check Python version compatibility
if sys.version_info >= (3, 8):
print("Python 3.8+ features available")
# Use walrus operator
data = [1, 2, 3, 4, 5]
if (n := len(data)) > 3:
print(f"List has {n} items")
else:
print("Upgrade to Python 3.8+ for latest features")
# Platform and implementation details
print(f"Platform: {sys.platform}")
print(f"Implementation: {sys.implementation.name}")
print(f"Implementation version: {sys.implementation.version}")
# Check for specific platforms
if sys.platform.startswith('win'):
print("Running on Windows")
elif sys.platform.startswith('darwin'):
print("Running on macOS")
elif sys.platform.startswith('linux'):
print("Running on Linux")
# Byte order (endianness)
print(f"Byte order: {sys.byteorder}")
# Maximum integer size
print(f"Max size: {sys.maxsize}")
python code snippet end
Module Search Path
python code snippet start
import sys
# Display module search paths
print("Python module search paths:")
for i, path in enumerate(sys.path):
print(f" {i}: {path}")
# Add custom module path
custom_path = "/path/to/my/modules"
if custom_path not in sys.path:
sys.path.insert(0, custom_path) # Add at beginning for highest priority
print(f"Added {custom_path} to sys.path")
# Remove a path
try:
sys.path.remove(custom_path)
print(f"Removed {custom_path} from sys.path")
except ValueError:
print(f"{custom_path} not in sys.path")
# Check if module can be imported
def can_import(module_name):
"""Check if a module can be imported"""
try:
__import__(module_name)
return True
except ImportError:
return False
print(f"Can import 'requests': {can_import('requests')}")
print(f"Can import 'json': {can_import('json')}")
# Find module location
import json
print(f"json module location: {json.__file__}")
python code snippet end
Standard Input, Output, and Error
python code snippet start
import sys
# Standard streams
print("This goes to stdout", file=sys.stdout)
print("This goes to stderr", file=sys.stderr)
# Read from stdin
print("Enter your name: ", end='')
sys.stdout.flush() # Force output before input
name = sys.stdin.readline().strip()
print(f"Hello, {name}!")
# Redirect output
import io
# Capture stdout
old_stdout = sys.stdout
sys.stdout = captured_output = io.StringIO()
print("This is captured")
print("This too")
# Restore stdout and get captured content
sys.stdout = old_stdout
captured_text = captured_output.getvalue()
print(f"Captured: {repr(captured_text)}")
# Context manager for output redirection
class CaptureOutput:
def __init__(self):
self.captured = io.StringIO()
def __enter__(self):
self.old_stdout = sys.stdout
sys.stdout = self.captured
return self
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stdout = self.old_stdout
def get_output(self):
return self.captured.getvalue()
# Usage
with CaptureOutput() as capture:
print("This is captured")
print("So is this")
print("Captured output:", repr(capture.get_output()))
python code snippet end
Exiting and Exception Handling
python code snippet start
import sys
def graceful_exit(message="", code=0):
"""Exit with optional message and code"""
if message:
print(message, file=sys.stderr)
sys.exit(code)
# Exit codes
def process_file(filename):
"""Process a file with proper exit codes"""
try:
with open(filename, 'r') as f:
content = f.read()
print(f"Processed {len(content)} characters")
return True
except FileNotFoundError:
print(f"Error: File '{filename}' not found", file=sys.stderr)
sys.exit(1) # File not found
except PermissionError:
print(f"Error: Permission denied for '{filename}'", file=sys.stderr)
sys.exit(2) # Permission error
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(3) # General error
# Exception information
def show_exception_info():
"""Display current exception information"""
exc_type, exc_value, exc_traceback = sys.exc_info()
if exc_type is not None:
print(f"Exception type: {exc_type.__name__}")
print(f"Exception value: {exc_value}")
print(f"Traceback object: {exc_traceback}")
else:
print("No current exception")
# Example with exception handling
try:
x = 1 / 0
except ZeroDivisionError:
print("Caught division by zero:")
show_exception_info()
# Exit handler
import atexit
def cleanup():
"""Function called on exit"""
print("Cleaning up before exit...")
atexit.register(cleanup)
# Uncomment to test exit
# graceful_exit("Goodbye!", 0)
python code snippet end
Memory and Performance Information
python code snippet start
import sys
# Memory usage
def get_object_size(obj):
"""Get size of object in bytes"""
return sys.getsizeof(obj)
# Compare memory usage of different data structures
data = list(range(1000))
print(f"List of 1000 integers: {get_object_size(data)} bytes")
data_tuple = tuple(range(1000))
print(f"Tuple of 1000 integers: {get_object_size(data_tuple)} bytes")
data_set = set(range(1000))
print(f"Set of 1000 integers: {get_object_size(data_set)} bytes")
data_dict = {i: i for i in range(1000)}
print(f"Dict of 1000 key-value pairs: {get_object_size(data_dict)} bytes")
# Deep memory analysis
def analyze_memory_usage(obj, name="object"):
"""Analyze memory usage of an object"""
size = sys.getsizeof(obj)
print(f"{name}: {size} bytes")
# For containers, analyze contents
if hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes)):
try:
items = list(obj)
if items:
item_sizes = [sys.getsizeof(item) for item in items[:10]] # First 10 items
avg_item_size = sum(item_sizes) / len(item_sizes)
print(f" Average item size: {avg_item_size:.1f} bytes")
print(f" Estimated total content: {avg_item_size * len(items):.0f} bytes")
except:
pass
# Example analysis
analyze_memory_usage([1, 2, 3, 4, 5], "Small list")
analyze_memory_usage(list(range(10000)), "Large list")
analyze_memory_usage("Hello, World!", "String")
# Reference count (CPython specific)
import sys
x = [1, 2, 3]
print(f"Reference count for x: {sys.getrefcount(x)}")
y = x # Create another reference
print(f"Reference count after y = x: {sys.getrefcount(x)}")
del y # Remove reference
print(f"Reference count after del y: {sys.getrefcount(x)}")
python code snippet end
Recursion and Call Stack
python code snippet start
import sys
# Recursion limit
print(f"Current recursion limit: {sys.getrecursionlimit()}")
# Set recursion limit (be careful!)
original_limit = sys.getrecursionlimit()
sys.setrecursionlimit(2000)
print(f"New recursion limit: {sys.getrecursionlimit()}")
# Restore original limit
sys.setrecursionlimit(original_limit)
# Test recursion depth
def recursive_function(depth=0):
"""Test function to demonstrate recursion depth"""
if depth > 10: # Prevent infinite recursion in demo
return depth
return recursive_function(depth + 1)
try:
max_depth = recursive_function()
print(f"Reached depth: {max_depth}")
except RecursionError:
print("Hit recursion limit")
# Stack frame inspection
import inspect
def stack_info():
"""Display current call stack information"""
frame = sys._getframe()
print("Current stack frames:")
depth = 0
while frame:
filename = frame.f_code.co_filename
line_number = frame.f_lineno
function_name = frame.f_code.co_name
print(f" {depth}: {function_name} in {filename}:{line_number}")
frame = frame.f_back
depth += 1
if depth > 10: # Limit output
break
def level1():
level2()
def level2():
level3()
def level3():
stack_info()
# Uncomment to see stack trace
# level1()
python code snippet end
Practical Command-Line Tools
File Processor Script
python code snippet start
#!/usr/bin/env python3
import sys
import os
def main():
"""Main function for file processing script"""
# Check arguments
if len(sys.argv) < 2:
print("Usage: python script.py <filename> [options]", file=sys.stderr)
print("Options:")
print(" --count Count lines")
print(" --upper Convert to uppercase")
print(" --verbose Verbose output")
sys.exit(1)
filename = sys.argv[1]
options = sys.argv[2:]
# Parse options
count_lines = '--count' in options
to_upper = '--upper' in options
verbose = '--verbose' in options
if verbose:
print(f"Processing file: {filename}")
print(f"Options: {options}")
# Check if file exists
if not os.path.exists(filename):
print(f"Error: File '{filename}' not found", file=sys.stderr)
sys.exit(1)
try:
with open(filename, 'r') as f:
lines = f.readlines()
if count_lines:
print(f"Line count: {len(lines)}")
if to_upper:
for i, line in enumerate(lines):
print(f"{i+1}: {line.upper().rstrip()}")
elif not count_lines: # Default: just display
for i, line in enumerate(lines):
print(f"{i+1}: {line.rstrip()}")
except PermissionError:
print(f"Error: Permission denied for '{filename}'", file=sys.stderr)
sys.exit(2)
except Exception as e:
print(f"Error processing file: {e}", file=sys.stderr)
sys.exit(3)
if __name__ == "__main__":
main()
python code snippet end
System Information Tool
python code snippet start
import sys
import platform
import os
def system_info():
"""Display comprehensive system information"""
print("=== Python System Information ===")
print(f"Python Version: {sys.version}")
print(f"Python Executable: {sys.executable}")
print(f"Platform: {sys.platform}")
print(f"Architecture: {platform.architecture()}")
print(f"Machine: {platform.machine()}")
print(f"Processor: {platform.processor()}")
print(f"System: {platform.system()} {platform.release()}")
print(f"\n=== Python Runtime ===")
print(f"Implementation: {sys.implementation.name}")
print(f"Implementation Version: {sys.implementation.version}")
print(f"Byte Order: {sys.byteorder}")
print(f"Max Integer Size: {sys.maxsize}")
print(f"Recursion Limit: {sys.getrecursionlimit()}")
print(f"\n=== Environment ===")
print(f"Current Working Directory: {os.getcwd()}")
print(f"Home Directory: {os.path.expanduser('~')}")
print(f"\n=== Module Search Paths ===")
for i, path in enumerate(sys.path[:5]): # Show first 5
print(f" {i}: {path}")
if len(sys.path) > 5:
print(f" ... and {len(sys.path) - 5} more paths")
print(f"\n=== Command Line ===")
if len(sys.argv) > 0:
print(f"Script: {sys.argv[0]}")
if len(sys.argv) > 1:
print(f"Arguments: {sys.argv[1:]}")
# Memory usage of common objects
print(f"\n=== Memory Usage Examples ===")
objects = [
("Empty list", []),
("List of 100 ints", list(range(100))),
("Empty dict", {}),
("Dict with 10 items", {i: i for i in range(10)}),
("String 'Hello'", "Hello"),
("String 100 chars", "x" * 100)
]
for name, obj in objects:
size = sys.getsizeof(obj)
print(f" {name}: {size} bytes")
if __name__ == "__main__":
# Check for help flag
if "--help" in sys.argv or "-h" in sys.argv:
print("System Information Tool")
print("Usage: python sysinfo.py [--help]")
print("Displays comprehensive Python system information")
sys.exit(0)
system_info()
python code snippet end
Environment Configuration Tool
python code snippet start
import sys
import os
import json
def manage_python_path():
"""Tool for managing Python module search paths"""
if len(sys.argv) < 2:
print("Python Path Manager")
print("Usage: python pathman.py <command> [arguments]")
print("Commands:")
print(" list - Show current paths")
print(" add <path> - Add path to sys.path")
print(" remove <path> - Remove path from sys.path")
print(" save <file> - Save current paths to file")
print(" load <file> - Load paths from file")
sys.exit(1)
command = sys.argv[1]
if command == "list":
print("Current Python module search paths:")
for i, path in enumerate(sys.path):
exists = "✓" if os.path.exists(path) else "✗"
print(f" {i:2d}: {exists} {path}")
elif command == "add":
if len(sys.argv) < 3:
print("Error: Please specify path to add")
sys.exit(1)
new_path = sys.argv[2]
if not os.path.exists(new_path):
print(f"Warning: Path '{new_path}' does not exist")
if new_path not in sys.path:
sys.path.insert(0, new_path)
print(f"Added '{new_path}' to sys.path")
else:
print(f"Path '{new_path}' already in sys.path")
elif command == "remove":
if len(sys.argv) < 3:
print("Error: Please specify path to remove")
sys.exit(1)
path_to_remove = sys.argv[2]
try:
sys.path.remove(path_to_remove)
print(f"Removed '{path_to_remove}' from sys.path")
except ValueError:
print(f"Path '{path_to_remove}' not found in sys.path")
elif command == "save":
if len(sys.argv) < 3:
print("Error: Please specify filename")
sys.exit(1)
filename = sys.argv[2]
path_data = {
'python_version': sys.version,
'platform': sys.platform,
'paths': sys.path
}
try:
with open(filename, 'w') as f:
json.dump(path_data, f, indent=2)
print(f"Saved {len(sys.path)} paths to '{filename}'")
except Exception as e:
print(f"Error saving to '{filename}': {e}")
sys.exit(1)
elif command == "load":
if len(sys.argv) < 3:
print("Error: Please specify filename")
sys.exit(1)
filename = sys.argv[2]
try:
with open(filename, 'r') as f:
path_data = json.load(f)
print(f"Loaded paths from '{filename}'")
print(f" Saved Python version: {path_data.get('python_version', 'unknown')}")
print(f" Saved platform: {path_data.get('platform', 'unknown')}")
for path in path_data.get('paths', []):
if path not in sys.path:
sys.path.append(path)
print(f" Added: {path}")
else:
print(f" Already present: {path}")
except FileNotFoundError:
print(f"Error: File '{filename}' not found")
sys.exit(1)
except json.JSONDecodeError:
print(f"Error: Invalid JSON in '{filename}'")
sys.exit(1)
except Exception as e:
print(f"Error loading from '{filename}': {e}")
sys.exit(1)
else:
print(f"Error: Unknown command '{command}'")
sys.exit(1)
if __name__ == "__main__":
manage_python_path()
python code snippet end
The sys module is essential for creating robust Python applications that need to interact with the runtime environment, handle command-line arguments, and manage system-specific functionality.
The sys module complements os module for system operations and supports module management through sys.path manipulation.
Reference: Python Sys Module Documentation