# Python by Structure: The Try/Else Block You're Not Using

Timothy slumped in his chair, staring at a function he'd written to load configuration files. "Margaret, I keep getting errors in the wrong places. When my config parser fails, it says 'file not found' even though the file exists. The structure feels... muddled."

Margaret leaned over to examine his code. "Ah, I see the problem. You're catching too broadly. Let me show you something most Python developers overlook - the `else` clause in error handling."

"The else? I thought that was just for if statements."

"That's the common misconception," Margaret said, pulling out a fresh sheet of paper. "Let's look at your code first, then I'll show you the proper structure."

Timothy's original attempt looked like this:

```python
def load_config(filename):
    try:
        with open(filename, 'r') as f:
            data = f.read()
        config = parse_config(data)
        validate_config(config)
        return config
    except FileNotFoundError:
        print(f"Config file '{filename}' not found")
        return None
    except ValueError as e:
        print(f"Invalid config: {e}")
        return None
```

"See the problem?" Margaret asked. "Everything happens in the `try` block. If `parse_config()` somehow raises a `FileNotFoundError`, your first exception handler catches it - even though the file was read successfully."

"Oh." Timothy grimaced. "So my error messages lie about what actually failed."

"Precisely. Now watch what happens when we use `else` to separate concerns."

Margaret rewrote the function:

```python
def load_config(filename):
    try:
        with open(filename, 'r') as f:
            data = f.read()
    except FileNotFoundError:
        print(f"Config file '{filename}' not found")
        return None
    else:
        try:
            config = parse_config(data)
            validate_config(config)
            return config
        except ValueError as e:
            print(f"Invalid config: {e}")
            return None
```

"Let me sketch out the structure," Margaret said, drawing the control flow:

**Tree View:**

```python
load_config(filename)
    Try
        With open(filename, 'r') as f
            data = f.read()
    Except FileNotFoundError
        print(f"Config file '{filename}' not found")
        Return None
    Else
        Try
            config = parse_config(data)
            validate_config(config)
            Return config
        Except ValueError
            print(f'Invalid config: {e}')
            Return None
```

Timothy studied the structure. "The `else` sits at the same level as `except`..."

"Exactly! And look at what that means in plain language."

**English View:**

```python
Function load_config(filename):
  Try:
    With open(filename, 'r') as f:
      Set data to f.read().
  Except FileNotFoundError:
    Evaluate print(f"Config file '{filename}' not found").
    Return None.
  Else:
    Try:
      Set config to parse_config(data).
      Evaluate validate_config(config).
      Return config.
    Except ValueError:
      Evaluate print(f'Invalid config: {e}').
      Return None.
```

"Oh!" Timothy's face brightened. "The `else` only runs if the file operation succeeds. So parsing errors can't trigger the wrong exception handler."

"Now you see it," Margaret smiled. "The structure creates a clear boundary. File access in the first `try`, data processing in the `else`. Each error gets caught in the right place."

Timothy traced the flow with his finger. "So the `else` block is saying 'this code assumes the try block succeeded.'"

"That's Python's philosophy showing through," Margaret said. "Be explicit about control flow. The `else` isn't decoration - it's a structural signal to anyone reading your code."

"I've been writing `try/except` for months and never once used `else`." Timothy shook his head. "How did I miss this?"

"Most developers do. It's in the documentation, but rarely taught. The structure makes it obvious once you see it - `else` belongs with error handling, not just conditionals."

Timothy saved his corrected function. "Next time I'm sequencing operations where early steps can fail, I'll think about what belongs in `else` - the code that assumes success."

"Now you're thinking structurally," Margaret said, returning to her desk. "The syntax is just Python. The structure is the logic underneath."

---

**Analyze Python structure yourself:** Download the [Python Structure Viewer](https://www.pacificw.com) - a free tool that shows code structure in tree and plain English views. Works offline, no installation required.

![Python Structure Viewer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7atyjd2na7r4dpmzdonb.png align="left")

---

*Aaron Rose is a software engineer and technology writer at* [*tech-reader.blog*](https://www.tech-reader.blog) *and the author of* [*Think Like a Genius*](https://amazon.com/author/aaron.rose)*.*
