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
257: The uuid Module for Unique Identifiers
I'm currently working on a prototype for a distributed task queue—basically a system where multiple workers pick up jobs from a shared pool. My first instinct for tracking these jobs was the classic approach: an incrementing integer. job_1, job_2, and so on. It works great on a single machine, but the moment I tried to run three different worker scripts on three different servers, they all started trying to create job_1 at the same time. Total chaos.
The failure of simple counting
# My initial (and flawed) logic
job_ids = []
def create_job(name):
job_id = len(job_ids) + 1
job_ids.append(job_id)
return f"job_{job_id}"
print(create_job("Email User")) # job_1
print(create_job("Clean Cache")) # job_2
If this code lives in one process, it's fine. But in a distributed system, there's no central "counter" without creating a massive bottleneck. I could use a database sequence, sure, but that means every single job creation requires a network round-trip to the DB just to get an ID. That's slow. I need a way to generate an ID that is practically guaranteed to be unique, even if the generator has no idea what other IDs have been created elsewhere.
Finding a better way with uuid
This is exactly why the uuid (Universally Unique Identifier) module exists. Instead of counting, it creates a 128-bit number. I'll start by trying the most common version, uuid4, which is essentially just a massive random number.
import uuid
# Let's generate a few and see what they look like
for _ in range(3):
print(uuid.uuid4())
# Output looks something like:
# 7b2e8f3a-1a2b-4c3d-8e9f-0a1b2c3d4e5f
# a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d
# f9e8d7c6-b5a4-4321-8765-4321fedcba98
That's a lot of characters, but the probability of two uuid4 calls resulting in the same ID is so astronomically low that for 99.9% of software engineering tasks, we treat it as impossible. I can now let my workers generate their own IDs locally without ever talking to each other, and they'll never collide.
Wait, what about uuid1?
While digging through the docs, I noticed uuid1(). I figured I'd try it out to see if it's "better" or just different. Let's see what happens when I run it a few times in quick succession.
import uuid
print(uuid.uuid1())
print(uuid.uuid1())
I noticed something immediately: the IDs look similar. That's because uuid1 isn't purely random; it uses the host's MAC address and the current timestamp. While this is useful if you need to know when or where an ID was generated, it's usually a bad idea for public-facing APIs. Why? Because you're essentially leaking your machine's hardware address to the world. Unless you have a very specific requirement for time-based sorting or traceability, stick with uuid4. I know I will.
Turning IDs into usable strings
One thing that tripped me up at first was that uuid.uuid4() doesn't return a string; it returns a UUID object. If I try to save that directly into a JSON file or a database that expects a string, it might complain.
import uuid
my_id = uuid.uuid4()
print(type(my_id)) # <class 'uuid.UUID'>
# To actually use it in a text-based system, I need to cast it
id_string = str(my_id)
print(id_string) # Now it's a standard string
It's a small detail, but skipping the str() conversion is a common "Why is my JSON failing?" bug I've seen in peer reviews. Always be explicit about the type when you're handing the ID off to another part of your application.
📋 Practical Task
Building a Unique Session Token Generator
Imagine you are building a login system. You cannot use simple integers for session tokens because users could easily guess other people's tokens by just adding 1 to their own (a classic security flaw called Insecure Direct Object Reference).
Write a Python script that does the following:
- Imports the
uuidmodule. - Creates a function called
generate_session_token()that returns a unique ID as a string. - Creates a dictionary called
active_sessionswhere the key is the session token and the value is a username (e.g., "Alice", "Bob"). - Simulate logging in three different users by calling your function and adding them to the dictionary.
- Print the final
active_sessionsdictionary to verify that each user has a unique, non-sequential token.
There are no comments for now.