- What is Sys module — system-specific parameters and functions
- argv — command-line arguments
- path — Python module search path
- stdin — reading from standard input
- stdout — writing to standard output
- stderr — writing to standard error
- exit — exiting a program
What is Sys Module?
The sys module provides access to system-specific parameters and functions. It lets you interact with the Python interpreter and the system it's running on.
Think of the sys module like a control panel for your Python program. You can use it to see what arguments were passed to your program, where Python looks for modules, what version of Python you're using, and more.
Unlike the os module (which deals with the operating system), the sys module deals with the Python runtime itself.
💡 Key concept: The sys module gives you access to the Python interpreter and system-related parameters.
Command-Line Arguments
Access Arguments Passed to Your Program
sys.argv is a list of command-line arguments passed to your Python program.
# Command-Line Arguments
import sys
print("=" * 50)
print("COMMAND-LINE ARGUMENTS")
print("=" * 50)
# ============================================================
# ACCESS ARGUMENTS
# ============================================================
print("\n1. ACCESS ARGUMENTS")
# sys.argv[0] is always the script name
print(f" Script name: {sys.argv[0]}")
# Print all arguments
print(f" All arguments: {sys.argv}")
# Print the number of arguments
print(f" Number of arguments: {len(sys.argv)}")
# ============================================================
# USING ARGUMENTS
# ============================================================
print("\n2. USING ARGUMENTS")
# Check if arguments were passed
if len(sys.argv) > 1:
print(" Arguments received:")
for i, arg in enumerate(sys.argv[1:], 1):
print(f" Arg {i}: {arg}")
else:
print(" No arguments passed")
# ============================================================
# SIMPLE COMMAND-LINE TOOL
# ============================================================
print("\n3. SIMPLE COMMAND-LINE TOOL")
def simple_tool():
"""A simple command-line tool"""
if len(sys.argv) < 2:
print(" Usage: python script.py [name]")
return
name = sys.argv[1]
print(f" Hello, {name}!")
# Uncomment to run:
# simple_tool()
# ============================================================
# ARGUMENT PARSING (Manual)
# ============================================================
print("\n4. MANUAL ARGUMENT PARSING")
def manual_parser():
"""Manually parse command-line arguments"""
args = sys.argv[1:]
for i in range(len(args)):
if args[i] == "--name" and i + 1 < len(args):
name = args[i + 1]
print(f" Name: {name}")
elif args[i] == "--help":
print(" Help: This is a sample tool")
elif args[i] == "--version":
print(" Version: 1.0")
# Uncomment to run:
# manual_parser()
# ============================================================
# USING ARGPARSE (Better Way)
# ============================================================
print("\n5. USING ARGPARSE (RECOMMENDED)")
print("""
For complex command-line arguments, use the argparse module:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--name", help="Your name")
parser.add_argument("--verbose", action="store_true")
args = parser.parse_args()
""")
# Demonstrate a simple version
if len(sys.argv) > 1 and sys.argv[1] == "--demo":
print(" Demo: Command-line parsing with argparse would be better!")
argv key points:
- sys.argv — list of command-line arguments
- sys.argv[0] — script name
- sys.argv[1:] — all arguments after script name
- len(sys.argv) — number of arguments
- argparse — better for complex arguments
Quick Check: What is sys.argv[0]? (Answer: The name of the script being executed)
System Path
Where Python Looks for Modules
sys.path is a list of directories where Python looks for modules to import.
# System Path
import sys
print("=" * 50)
print("SYSTEM PATH")
print("=" * 50)
# ============================================================
# VIEW THE PATH
# ============================================================
print("\n1. VIEW THE PATH")
# sys.path is a list of directories
print(" Python module search path:")
for i, path in enumerate(sys.path):
print(f" {i+1}. {path}")
# ============================================================
# ADD A DIRECTORY TO PATH
# ============================================================
print("\n2. ADD A DIRECTORY TO PATH")
# Add a directory to the path
new_path = "/my/custom/modules"
sys.path.append(new_path)
print(f" Added: {new_path}")
# Check if it's there
print(f" Is '{new_path}' in path? {new_path in sys.path}")
# ============================================================
# REMOVE A DIRECTORY FROM PATH
# ============================================================
print("\n3. REMOVE A DIRECTORY FROM PATH")
# Remove the path we added
if new_path in sys.path:
sys.path.remove(new_path)
print(f" Removed: {new_path}")
print(f" Is '{new_path}' in path? {new_path in sys.path}")
# ============================================================
# IMPORT FROM CUSTOM PATH
# ============================================================
print("\n4. IMPORT FROM CUSTOM PATH")
print("""
# To import a module from a custom directory:
import sys
sys.path.append("/path/to/your/module")
import your_module
""")
# ============================================================
# SYSTEM PATHS SUMMARY
# ============================================================
print("\n5. PATH SUMMARY")
print(f" Number of paths: {len(sys.path)}")
print(f" First path: {sys.path[0]}") # Usually the script's directory
print(f" Last path: {sys.path[-1]}")
sys.path key points:
- sys.path — list of directories for module search
- sys.path.append() — add a directory
- sys.path.remove() — remove a directory
- First path — usually the script's directory
Quick Check: What does sys.path contain? (Answer: A list of directories where Python looks for modules)
Standard Input
Reading from Standard Input
sys.stdin is the standard input stream. You can use it to read input from the user or from a pipe.
# Standard Input
import sys
print("=" * 50)
print("STANDARD INPUT")
print("=" * 50)
# ============================================================
# READING A SINGLE LINE
# ============================================================
print("\n1. READING A SINGLE LINE")
def read_line_example():
print(" Enter a line of text:")
line = sys.stdin.readline()
print(f" You entered: {line.strip()}")
# Uncomment to test:
# read_line_example()
# ============================================================
# READING INPUT WITH PROMPT
# ============================================================
print("\n2. READING INPUT WITH PROMPT")
def read_with_prompt():
sys.stdout.write(" Enter your name: ")
sys.stdout.flush()
name = sys.stdin.readline().strip()
print(f" Hello, {name}!")
# Uncomment to test:
# read_with_prompt()
# ============================================================
# READING ALL INPUT
# ============================================================
print("\n3. READING ALL INPUT")
def read_all():
print(" Enter multiple lines (Ctrl+D to finish):")
lines = sys.stdin.read()
print(f" You entered {len(lines)} characters")
# Uncomment to test:
# read_all()
# ============================================================
# READING LINE BY LINE (Efficient)
# ============================================================
print("\n4. READING LINE BY LINE")
def read_lines():
print(" Processing lines (Enter 'quit' to stop):")
for line in sys.stdin:
line = line.strip()
if line.lower() == "quit":
break
print(f" Processing: {line}")
# Uncomment to test:
# read_lines()
# ============================================================
# USING SYS.STDIN WITH INPUT()
# ============================================================
print("\n5. USING INPUT() FUNCTION")
print("""
The input() function is a simpler wrapper around sys.stdin:
name = input("Enter your name: ")
print(f"Hello, {name}!")
input() reads from sys.stdin and strips the newline.
""")
# ============================================================
# SYS.STDIN VS INPUT()
# ============================================================
print("\n6. SYS.STDIN VS INPUT()")
print("""
input() vs sys.stdin:
- input() reads one line and strips the newline
- input() can show a prompt
- sys.stdin.readline() is more flexible
- sys.stdin.read() reads everything
- sys.stdin is an object with more methods
""")
stdin key points:
- sys.stdin — standard input stream
- sys.stdin.readline() — read one line
- sys.stdin.read() — read all input
- input() — simpler wrapper for stdin
Quick Check: What's the difference between input() and sys.stdin.readline()? (Answer: input() strips the newline and can show a prompt)
Standard Output
Writing to Standard Output
sys.stdout is the standard output stream. It's what print() uses by default.
# Standard Output
import sys
print("=" * 50)
print("STANDARD OUTPUT")
print("=" * 50)
# ============================================================
# WRITING TO STDOUT
# ============================================================
print("\n1. WRITING TO STDOUT")
# Using sys.stdout.write
sys.stdout.write(" Hello from sys.stdout!\n")
# print() uses sys.stdout by default
print(" Hello from print()!")
# ============================================================
# REDIRECTING OUTPUT
# ============================================================
print("\n2. REDIRECTING OUTPUT")
import io
# Capture output in a string buffer
buffer = io.StringIO()
# Save original stdout
original_stdout = sys.stdout
# Redirect stdout to buffer
sys.stdout = buffer
# Print something (goes to buffer)
print(" This goes to the buffer")
print(" This also goes to the buffer")
# Restore stdout
sys.stdout = original_stdout
# Get captured output
captured = buffer.getvalue()
print(f" Captured output: {captured}")
# ============================================================
# WRITING WITHOUT NEWLINE
# ============================================================
print("\n3. WRITING WITHOUT NEWLINE")
# sys.stdout.write doesn't add a newline
sys.stdout.write(" First part")
sys.stdout.write(" Second part")
sys.stdout.write("\n") # Add newline manually
# ============================================================
# FLUSHING OUTPUT
# ============================================================
print("\n4. FLUSHING OUTPUT")
import time
print(" Printing with delays (flush=True):")
for i in range(3):
print(f" Step {i+1}", end=" ", flush=True)
time.sleep(0.5)
print("Done!")
# ============================================================
# PRINT() VS SYS.STDOUT.WRITE()
# ============================================================
print("\n5. PRINT() VS SYS.STDOUT.WRITE()")
print("""
print() vs sys.stdout.write():
- print() adds a newline by default
- print() can take multiple arguments
- sys.stdout.write() is lower-level
- sys.stdout.write() doesn't add a newline
- print() is more convenient for most cases
""")
stdout key points:
- sys.stdout — standard output stream
- sys.stdout.write() — write to stdout
- Redirection — can redirect stdout to a file or buffer
- flush — force output immediately
Quick Check: What does print() use by default? (Answer: sys.stdout)
Standard Error
Writing Errors Separately
sys.stderr is the standard error stream. It's used for error messages and can be redirected separately from stdout.
# Standard Error
import sys
print("=" * 50)
print("STANDARD ERROR")
print("=" * 50)
# ============================================================
# WRITING TO STDERR
# ============================================================
print("\n1. WRITING TO STDERR")
# Write to stderr
sys.stderr.write(" This is an error message\n")
# print() doesn't default to stderr
print(" This goes to stdout")
# ============================================================
# ERRORS VS OUTPUT
# ============================================================
print("\n2. ERRORS VS OUTPUT")
# Print to stdout
sys.stdout.write(" Normal output\n")
# Print to stderr
sys.stderr.write(" Error output\n")
print(" stdout and stderr can be redirected separately!")
# ============================================================
# REDIRECTING STDERR
# ============================================================
print("\n3. REDIRECTING STDERR")
import io
# Save original stderr
original_stderr = sys.stderr
# Redirect stderr to buffer
error_buffer = io.StringIO()
sys.stderr = error_buffer
# Write an error (goes to buffer)
sys.stderr.write(" Error 1\n")
sys.stderr.write(" Error 2\n")
# Restore stderr
sys.stderr = original_stderr
# Get captured errors
captured_errors = error_buffer.getvalue()
print(f" Captured errors: {captured_errors}")
# ============================================================
# USING SYS.EXCEPTION
# ============================================================
print("\n4. USING SYS.EXCEPTION")
try:
# Simulate an error
x = 1 / 0
except Exception as e:
# Get exception info
exc_type, exc_value, exc_traceback = sys.exc_info()
print(f" Exception type: {exc_type}")
print(f" Exception value: {exc_value}")
# ============================================================
# BEST PRACTICE: USE STDOUT FOR OUTPUT, STDERR FOR ERRORS
# ============================================================
print("\n5. BEST PRACTICE")
print("""
Best practice:
- Use stdout for normal program output
- Use stderr for error messages
- This allows users to redirect each separately:
python script.py > output.txt 2> errors.txt
""")
stderr key points:
- sys.stderr — standard error stream
- sys.stderr.write() — write to stderr
- Separate streams — stdout and stderr can be redirected separately
- sys.exc_info() — get exception information
Quick Check: Why should you use stderr for error messages? (Answer: So errors can be redirected separately from normal output)
Exiting a Program
Exit Your Program with sys.exit()
sys.exit() exits the Python program. You can provide an optional exit code.
# Exiting a Program
import sys
print("=" * 50)
print("EXITING A PROGRAM")
print("=" * 50)
# ============================================================
# BASIC EXIT
# ============================================================
print("\n1. BASIC EXIT")
def exit_demo():
print(" About to exit...")
sys.exit()
print(" This line never runs") # Unreachable
# Uncomment to test:
# exit_demo()
# ============================================================
# EXIT WITH CODE
# ============================================================
print("\n2. EXIT WITH CODE")
def exit_with_code():
print(" Exiting with code 1 (error)")
sys.exit(1)
# Uncomment to test:
# exit_with_code()
# ============================================================
# CATCHING EXIT
# ============================================================
print("\n3. CATCHING EXIT")
try:
sys.exit(" Exiting with a message")
except SystemExit as e:
print(f" Caught SystemExit: {e}")
# ============================================================
# EXIT CODES
# ============================================================
print("\n4. EXIT CODES")
print("""
Common exit codes:
- 0: Success (program ran without errors)
- 1: General error
- 2: Command line usage error
- 13: Permission denied
- 127: Command not found
- 130: Interrupted by Ctrl+C
""")
print(" Use sys.exit(0) for success, sys.exit(1) for errors")
# ============================================================
# EXIT MESSAGE
# ============================================================
print("\n5. EXIT MESSAGE")
def exit_with_message():
print(" This is an error message")
sys.exit(" Exiting with a message")
# Uncomment to test:
# exit_with_message()
sys.exit() key points:
- sys.exit() — exits the program
- sys.exit(0) — success
- sys.exit(1) — error
- SystemExit — can be caught with try/except
Quick Check: What exit code indicates success? (Answer: 0)
Real-World Example
Building a Command-Line Tool
# Real-World Example: Command-Line Tool
import sys
import os
import time
print("=" * 60)
print("COMMAND-LINE TOOL")
print("=" * 60)
# ============================================================
# FILE PROCESSOR TOOL
# ============================================================
class FileProcessor:
"""A simple command-line file processor"""
def __init__(self, filename):
self.filename = filename
self.lines = []
def load(self):
"""Load the file"""
try:
with open(self.filename, 'r') as f:
self.lines = f.readlines()
return True
except FileNotFoundError:
return False
def count_lines(self):
"""Count lines in the file"""
return len(self.lines)
def count_words(self):
"""Count words in the file"""
total = 0
for line in self.lines:
total += len(line.split())
return total
def count_chars(self):
"""Count characters in the file"""
total = 0
for line in self.lines:
total += len(line)
return total
def show_stats(self):
"""Show file statistics"""
print(f" File: {self.filename}")
print(f" Lines: {self.count_lines()}")
print(f" Words: {self.count_words()}")
print(f" Characters: {self.count_chars()}")
def search(self, pattern):
"""Search for a pattern in the file"""
matches = []
for i, line in enumerate(self.lines, 1):
if pattern.lower() in line.lower():
matches.append((i, line.strip()))
return matches
# ============================================================
# MAIN FUNCTION
# ============================================================
def main():
"""Main entry point for the tool"""
print("\n" + "=" * 50)
print("FILE PROCESSOR TOOL")
print("=" * 50)
# Check arguments
if len(sys.argv) < 2:
sys.stderr.write(" Error: No filename provided\n")
sys.stderr.write(" Usage: python script.py [filename] [options]\n")
sys.stderr.write(" Options: --stats, --search PATTERN\n")
sys.exit(1)
filename = sys.argv[1]
# Check if file exists
if not os.path.exists(filename):
sys.stderr.write(f" Error: File '{filename}' not found\n")
sys.exit(1)
# Create processor
processor = FileProcessor(filename)
if not processor.load():
sys.stderr.write(f" Error: Could not load file '{filename}'\n")
sys.exit(1)
# Parse options
if len(sys.argv) == 2:
# No options - show stats
processor.show_stats()
elif len(sys.argv) == 3:
option = sys.argv[2]
if option == "--stats":
processor.show_stats()
else:
sys.stderr.write(f" Error: Unknown option '{option}'\n")
sys.exit(1)
elif len(sys.argv) >= 4:
option = sys.argv[2]
if option == "--search":
pattern = sys.argv[3]
matches = processor.search(pattern)
if matches:
print(f" Found {len(matches)} matches:")
for line_num, line in matches:
print(f" Line {line_num}: {line[:50]}...")
else:
print(f" No matches found for '{pattern}'")
else:
sys.stderr.write(f" Error: Unknown option '{option}'\n")
sys.exit(1)
# ============================================================
# DEMONSTRATION
# ============================================================
print("\n1. CREATING SAMPLE FILE")
with open("sample.txt", "w") as f:
f.write("Line 1: Hello World\n")
f.write("Line 2: Python is great\n")
f.write("Line 3: This is a sample\n")
f.write("Line 4: Hello Python\n")
f.write("Line 5: Goodbye World\n")
print(" Created sample.txt")
print("\n2. RUNNING TOOL")
# Simulate command-line arguments
print(" Command: python script.py sample.txt")
print(" Output:")
print(" " + "-" * 20)
# Run with sample file
sys.argv = ["script.py", "sample.txt"]
main()
print("\n Command: python script.py sample.txt --search hello")
print(" Output:")
print(" " + "-" * 20)
sys.argv = ["script.py", "sample.txt", "--search", "hello"]
main()
print("\n Command: python script.py missing.txt")
print(" Output:")
print(" " + "-" * 20)
sys.argv = ["script.py", "missing.txt"]
main()
print("\n3. CLEANUP")
os.remove("sample.txt")
print(" Removed sample.txt")
print("\n" + "=" * 60)
print("KEY TAKEAWAYS:")
print("=" * 60)
print("""
- sys.argv for command-line arguments
- sys.stderr for error messages
- sys.exit() for exiting with codes
- Build command-line tools efficiently
- Use stdout for output, stderr for errors
""")
Real-world example key points:
- sys.argv — parse command-line arguments
- sys.stderr — show error messages
- sys.exit() — exit with error codes
- File processing — practical application
Quick Check: What would you use to create a command-line tool? (Answer: sys.argv for arguments, sys.stderr for errors, sys.exit for exiting)
Best Practices
Using Sys Module Effectively
# Best Practices for Sys Module
import sys
print("=" * 60)
print("BEST PRACTICES FOR SYS MODULE")
print("=" * 60)
# ============================================================
# 1. CHECK ARGUMENTS BEFORE USING
# ============================================================
print("\n1. CHECK ARGUMENTS BEFORE USING")
# Good - check length
if len(sys.argv) < 2:
print(" Usage: python script.py [args]")
sys.exit(1)
# Bad - using without checking
# filename = sys.argv[1] # Could be IndexError
# ============================================================
# 2. USE STDERR FOR ERRORS
# ============================================================
print("\n2. USE STDERR FOR ERRORS")
# Good - use stderr for errors
sys.stderr.write(" Error: Something went wrong\n")
# Bad - using stdout for errors
# print(" Error: Something went wrong")
# ============================================================
# 3. USE EXIT CODES APPROPRIATELY
# ============================================================
print("\n3. USE EXIT CODES APPROPRIATELY")
def process_file(filename):
try:
with open(filename, 'r') as f:
return f.read()
except FileNotFoundError:
sys.stderr.write(f" Error: File '{filename}' not found\n")
sys.exit(1)
except PermissionError:
sys.stderr.write(f" Error: Permission denied for '{filename}'\n")
sys.exit(13)
except Exception as e:
sys.stderr.write(f" Error: {e}\n")
sys.exit(1)
# ============================================================
# 4. DON'T MODIFY SYS.PATH UNLESS NECESSARY
# ============================================================
print("\n4. DON'T MODIFY SYS.PATH UNLESS NECESSARY")
# Good - only add when needed
import os
custom_path = os.path.join(os.getcwd(), "lib")
if os.path.exists(custom_path) and custom_path not in sys.path:
sys.path.append(custom_path)
# ============================================================
# 5. HANDLE SYSTEMEXIT
# ============================================================
print("\n5. HANDLE SYSTEMEXIT")
def cleanup():
print(" Cleaning up...")
try:
# Do work
if len(sys.argv) < 2:
cleanup()
sys.exit(1)
# More work...
except SystemExit:
cleanup()
raise # Re-raise to exit
# ============================================================
# 6. USE ARGPARSE FOR COMPLEX ARGUMENTS
# ============================================================
print("\n6. USE ARGPARSE FOR COMPLEX ARGUMENTS")
print("""
For complex command-line arguments, use argparse:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="File to process")
parser.add_argument("--verbose", "-v", action="store_true")
parser.add_argument("--output", "-o", help="Output file")
args = parser.parse_args()
""")
# ============================================================
# 7. SUMMARY
# ============================================================
print("\n" + "=" * 60)
print("BEST PRACTICES SUMMARY")
print("=" * 60)
print("""
- Check sys.argv length before accessing
- Use sys.stderr for error messages
- Use appropriate exit codes
- Don't modify sys.path unless necessary
- Handle SystemExit for cleanup
- Use argparse for complex arguments
- sys.exit(0) for success, sys.exit(1) for errors
""")
Best practices summary:
- Check arguments — before using sys.argv
- Use stderr — for error messages
- Exit codes — use appropriate values
- Don't modify sys.path — unless necessary
- Handle SystemExit — for cleanup
- Use argparse — for complex arguments
Quick Check: What should you use for complex command-line arguments? (Answer: The argparse module)
Try It Yourself
Experiment with the sys module in the editor below.
SYS MODULE - PRACTICE
==================================================
1. COMMAND-LINE ARGUMENTS
Script name: script.py
Arguments: []
Number of args: 1
2. SYSTEM PATH
Python search path:
1. /home/user
2. /usr/lib/python3.10
3. /usr/lib/python3.10/lib-dynload
... and 5 more
3. STANDARD INPUT/OUTPUT
This goes to stdout
This goes to stderr
print() also goes to stdout
4. SYSTEM INFORMATION
Python version: 3.10.0 (default, Oct 4 2024, 12:00:00) [GCC 9.4.0]
Platform: linux
Max integer size: 9223372036854775807
Byte order: little
Python executable: /usr/bin/python3
You've Got It!
You now understand the sys module in Python. You know how to use command-line arguments, standard streams, system paths, and exit codes.
Quick Quiz
Test what you've learned:
Frequently Asked Questions
What is the sys module in Python?
What's the difference between sys and os modules?
How do I get command-line arguments?
sys.argv. It's a list where sys.argv[0] is the script name and sys.argv[1:] are the arguments. For complex arguments, use the argparse module.
How do I exit a Python program?
sys.exit(). You can provide an exit code: sys.exit(0) for success, sys.exit(1) for error. You can also provide a message: sys.exit("Error message").
Can I redirect stdout and stderr?
sys.stdout and sys.stderr. This is useful for capturing output or writing to files.
What's the difference between print() and sys.stdout.write()?
Where to Go From Here
Now that you understand the sys module, check out these related topics:
Random Module
Learn about generating random numbers and choices.
Learn More →Math Module
Learn about mathematical functions and constants.
Learn More →OS Module
Learn more about operating system interactions.
Learn More →