Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
260: The configparser Module for Config Files
I see this all the time: a developer needs to save some application settings, so they immediately reach for a JSON file. It seems like the logical choice because we use JSON for everything else. But here is the problem: JSON is a data interchange format, not a configuration format. If you give a JSON config file to a non-technical user or a sysadmin, one missing comma or a misplaced curly brace will crash your entire application on startup. It's fragile for humans to edit by hand.
JSON is the only way to store settings
# The "fragile" way (settings.json)
{
"database": {
"host": "localhost",
"port": 5432,
"debug": true,
} # Oops! That trailing comma here is valid in Python dicts,
# but it's a syntax error in standard JSON.
# Your app just crashed.
Using INI files for human-friendly configuration
This is where the configparser module comes in. It handles INI files, which are structured into [sections] and key = value pairs. They are far more forgiving. If someone adds an extra space or a comment line, the parser doesn't blink. I personally prefer INI files for local tool configurations because they feel "native" to the OS environment.
Let's look at how we actually implement this. First, imagine we have a file called config.ini:
[server]
host = 127.0.0.1
port = 8080
debug = yes
[auth]
api_key = secret_key_123
timeout = 30
To get this data into Python, you initialize a ConfigParser object and read the file. Notice that the object behaves a lot like a nested dictionary:
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
# Accessing values is straightforward
host = config['server']['host']
print(f"Connecting to {host}...")
# Output: Connecting to 127.0.0.1...
Handling Types: Beyond the String
Here is the "gotcha" that trips up almost everyone the first time they use this module: everything is a string. If you access config['server']['port'], you won't get the integer 8080; you'll get the string "8080". If you try to add 1 to that, Python will throw a TypeError.
You could wrap everything in int() or bool(), but configparser has built-in getter methods that handle this more gracefully, especially for booleans (it recognizes 'yes', 'no', 'true', 'false', 'on', and 'off').
# The wrong way
port = int(config['server']['port'])
# The professional way
port = config.getint('server', 'port')
is_debug = config.getboolean('server', 'debug')
print(f"Port is {type(port)} and Debug is {type(is_debug)}")
# Output: Port is <class 'int'> and Debug is <class 'bool'>
Updating Settings Programmatically
Sometimes your app needs to update its own configuration—perhaps a user changes a setting in a UI. You can modify the ConfigParser object just like a dictionary, but remember that this only changes the data in memory. To make it permanent, you have to write the object back to the file.
# Update the API key
config['auth']['api_key'] = 'new_rotated_key_456'
# Save the changes back to the disk
with open('config.ini', 'w') as configfile:
config.write(configfile)
One quick tip: always use a context manager (the with statement) when writing the file. It ensures the file handle is closed properly even if something goes sideways during the write process.
📋 Practical Task
Build a Persistent Application Environment Manager
You are building a tool that needs to track the current environment (Development, Testing, or Production) and a set of thresholds for a monitoring system. Your task is to implement a configuration manager that handles these settings.
Requirements:
- Create a file named
app_settings.iniwith two sections:[env]and[thresholds].[env]should containmode = developmentandversion = 1.0.[thresholds]should containmax_retries = 5andalert_enabled = yes.
- Write a Python script that:
- Reads the
app_settings.inifile. - Prints the
max_retriesas an integer andalert_enabledas a boolean. - Updates the
modein the[env]section to"production". - Saves the updated configuration back to the file.
- Reads the
Validation: After running your script, open app_settings.ini to verify that mode has been changed to production while all other settings remained intact.
There are no comments for now.