Of course! Using CodeMirror with Python involves a few different scenarios, depending on whether you're working on a frontend (in the browser) or a backend (on a server).

Let's break it down.
Scenario 1: Using CodeMirror in a Frontend Web Application (Most Common)
This is the typical use case. You have a web page (HTML) and you want to embed a Python code editor. You'll use JavaScript to initialize CodeMirror on a <textarea> element.
Step 1: Include CodeMirror in your HTML
You can either download the CodeMirror library and host it yourself or use a CDN (Content Delivery Network). Using a CDN is the easiest for quick projects.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">Python Code Editor with CodeMirror</title>
<!-- 1. Include the CodeMirror CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css"> <!-- Optional: A popular theme -->
<!-- 2. Include the Python mode and any other addons you need -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/python/python.min.js"></script>
<!-- Addons like linter, autocomplete, etc. go here -->
</head>
<body>
<h1>Python Code Editor</h1>
<textarea id="python-editor"># Welcome to the Python editor
# You can write and edit Python code here
def greet(name):
"""A simple function to greet someone."""
print(f"Hello, {name}!")
greet("CodeMirror User")</textarea>
<!-- 3. Include your custom JavaScript to initialize the editor -->
<script src="app.js"></script>
</body>
</html>
Step 2: Initialize CodeMirror with JavaScript (in app.js)
This script finds the <textarea> and turns it into a fully-featured CodeMirror editor.

// app.js
// Wait for the DOM to be fully loaded
document.addEventListener('DOMContentLoaded', (event) => {
// Find the textarea by its ID
const textarea = document.getElementById('python-editor');
// Create a new CodeMirror instance
const editor = CodeMirror.fromTextArea(textarea, {
// Configuration options
mode: 'python', // Set the language mode
theme: 'monokai', // Set the theme
lineNumbers: true, // Show line numbers
indentUnit: 4, // Set indentation to 4 spaces
lineWrapping: true, // Wrap long lines
autofocus: true, // Focus the editor on load
});
// Optional: You can listen for changes in the editor
editor.on('change', (instance, change) => {
// 'instance' is the CodeMirror editor instance
// 'change' is an object describing the change
// You can get the current code like this:
const code = instance.getValue();
console.log('Code changed:', code);
});
});
Key Addons for a Better Python Experience
For a more robust editor, you'll want to add addons. You need to include their CSS and JS files and then configure them.
Example: Adding Autocomplete (IntelliSense)
-
Add the addon files in your HTML:
<!-- Add these inside the <head> or <body> --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/show-hint.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/show-hint.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/python-hint.min.js"></script>
-
Configure it in your JavaScript:
(图片来源网络,侵删)// In app.js, when initializing the editor const editor = CodeMirror.fromTextArea(textarea, { // ... other options extraKeys: { "Ctrl-Space": "autocomplete" // Bind autocomplete to Ctrl+Space } });
Example: Adding a Linter (for syntax errors)
-
Add the addon files:
<!-- Add these inside the <head> or <body> --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/lint/lint.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/lint/lint.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/lint/python-lint.min.js"></script>
-
Configure it:
// In app.js const editor = CodeMirror.fromTextArea(textarea, { // ... other options mode: 'python', lint: true // Enable linting });
Scenario 2: Running the Python Code on a Backend
A browser cannot execute Python code directly (it only understands JavaScript). To run the Python code written in the CodeMirror editor, you need to send it to a backend server.
The typical workflow is:
- User writes Python code in the CodeMirror editor (frontend).
- User clicks a "Run" button.
- JavaScript sends the code to your Python backend (e.g., using
fetchAPI). - The Python server executes the code safely (using a sandboxed environment).
- The server sends the output (stdout, stderr) back to the frontend.
- The frontend displays the output.
Simple Backend Example using Flask
Here’s a basic Python Flask server that can receive code, run it, and return the output.
Install Flask
pip install Flask
Create a Flask app (app.py)
from flask import Flask, request, jsonify
import io
import sys
import subprocess
import ast
app = Flask(__name__)
def execute_python_code(code):
"""
Safish execution of Python code.
WARNING: This is NOT secure for untrusted code. Do not use this
in a production environment with public access. This is a simplified example.
"""
# Capture stdout
old_stdout = sys.stdout
sys.stdout = captured_output = io.StringIO()
try:
# Use ast.parse to check for syntax errors before execution
ast.parse(code)
# Execute the code
exec(code, globals())
except SyntaxError as e:
return f"Syntax Error: {e}"
except Exception as e:
return f"Error: {e}"
finally:
# Restore stdout
sys.stdout = old_stdout
return captured_output.getvalue()
@app.route('/run', methods=['POST'])
def run_code():
data = request.get_json()
if not data or 'code' not in data:
return jsonify({'error': 'No code provided'}), 400
code = data['code']
output = execute_python_code(code)
return jsonify({'output': output})
if __name__ == '__main__':
app.run(debug=True)
Update your Frontend JavaScript (app.js)
Modify your JavaScript to send the code to the Flask backend when a button is clicked.
// app.js
document.addEventListener('DOMContentLoaded', (event) => {
const textarea = document.getElementById('python-editor');
const editor = CodeMirror.fromTextArea(textarea, {
mode: 'python',
theme: 'monokai',
lineNumbers: true,
lineWrapping: true,
});
// Get references to the button and output div
const runButton = document.getElementById('run-button');
const outputDiv = document.getElementById('output');
runButton.addEventListener('click', () => {
const code = editor.getValue();
// Clear previous output
outputDiv.textContent = 'Running...';
// Send the code to the backend
fetch('/run', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code: code }),
})
.then(response => response.json())
.then(data => {
if (data.error) {
outputDiv.textContent = `Error: ${data.error}`;
} else {
outputDiv.textContent = data.output;
}
})
.catch(error => {
console.error('Error:', error);
outputDiv.textContent = 'An error occurred while running the code.';
});
});
});
Update your HTML (index.html)
Add a button and a place to show the output.
<!-- ... inside the <body> ... --> <h1>Python Code Editor</h1> <button id="run-button">Run Code</button> <pre id="output"></pre> <!-- ... the rest of the HTML ... -->
Scenario 3: Using CodeMirror as a Library in a Python Desktop App
This is a more advanced and less common use case. You would use a Python framework that can embed a web browser, such as PyQt/PySide or Tkinter (with its webview).
The basic idea is:
- You create a desktop application window.
- Inside that window, you embed a web view (which is essentially a mini-browser).
- You load your HTML/JS/CodeMirror application into that web view.
- Your Python code and the JavaScript code in the web view communicate with each other.
This is complex to set up and is usually only done if you need the rich features of a web-based editor within a desktop application. For most desktop Python editors, a native widget library like QScintilla (used by Spyder) is a more direct approach.
