Cloud Tech by Victor

Search

30 results for “python

Search results

Backend

Python Async Programming

How asyncio's single-threaded event loop achieves concurrency without threads, why blocking calls silently defeat it, and when async actually helps versus when it's pure overhead.

Backend

Python Data Structures

When to reach for a list, tuple, dict, or set based on what operations you actually need fast, and why choosing the wrong one is a common hidden performance bug.

Backend

Python Syntax Fundamentals

How Python's significant whitespace, dynamic typing, and object model shape idiomatic code, and the mutable-default-argument trap that catches almost everyone once.

Backend

Python Virtual Environments & Packaging

Why every Python project needs an isolated environment, what a lockfile actually pins down that a requirements list doesn't, and how to avoid the global-install dependency trap.

Backend

Python Web Frameworks Overview

How Flask, Django, and FastAPI trade minimalism, batteries-included structure, and async-first design differently, and how to actually choose based on project shape.

Recursion & the Call Stack

Python's own documentation warns that raising the recursion limit "should be done with care, because a too-high limit can lead to a crash." Why doesn't raising the limit simply allow deeper, safe recursion?

The recursion limit is a proxy for the real constraint, actual available C stack space, which is platform-dependent and finite regardless of what the configured limit says. Setting the limit higher than the platform's actual available stack can support doesn't create more stack space, it just removes the early warning that would have raised a clean `RecursionError`, so recursion can now run deep enough to exhaust the real stack and crash the process with a low-level segmentation fault instead, a worse failure mode than the exception the limit was preventing in the first place.

Roadmap

Python Developer Roadmap

From syntax and data structures through tooling, testing, async programming, and web frameworks, the core path for a working Python developer, linked into Cloud Tech by Victor topic references.

Backend

Testing Python with pytest

How pytest's fixture system and plain-assert philosophy replace unittest's boilerplate, and why fixture scope is the setting most likely to cause confusing test failures.

Hash Tables & the Hash/Equality Contract

Why does Python's documentation say a class defining mutable objects with a custom __eq__ should not implement __hash__ at all?

If an object's hash is derived from fields that can change after the object is already stored as a dict key, mutating it changes its hash value, but the object stays in whatever bucket it was originally placed in based on the old hash, so a subsequent lookup computes the new hash, looks in the new (wrong) bucket, and fails to find an object that is, in fact, still in the dictionary. Making a mutable object unhashable by default (which not defining `__hash__` effectively signals) prevents this specific class of bug entirely, at the cost of not being able to use that object as a dict key or set member at all, a deliberate, documented trade-off favoring correctness over convenience.

Python Syntax Fundamentals

Why does Python use indentation instead of braces to define code blocks, and what problem does this create?

Python uses indentation as syntax specifically to force a consistent visual structure, code that looks nested is nested, with no possibility of a brace mismatch making the visual and actual structure disagree, a real class of bugs in brace-delimited languages. The trade-off is that whitespace becomes semantically meaningful: mixing tabs and spaces, or an accidentally misaligned line, is a syntax error (or worse, silently changes which block a line belongs to) rather than a cosmetic issue. Python 3 disallows mixing tabs and spaces in the same file specifically to prevent the silent version of this problem.

Python Syntax Fundamentals

Why is using a mutable object (like a list) as a default argument value a common bug in Python?

Default argument values are evaluated exactly once, when the function is defined, not on every call, so a mutable default like `def f(items=[])` creates one list object that is shared across every call that doesn't explicitly pass its own `items`. Appending to it in one call leaves those items present the next time the function is called with the default, which looks like inexplicable state leaking between unrelated calls. The fix is defaulting to `None` and creating a new list inside the function body when `items is None`, so every call that needs the default gets its own fresh object.

Python Syntax Fundamentals

What is the difference between `is` and `==` in Python?

`==` calls the object's `__eq__` method and checks value equality, whether two objects represent the same value, even if they are different objects in memory. `is` checks identity, whether two names refer to the exact same object in memory. Two separate list literals with identical contents are `==` but not `is`, because they're distinct objects with equal values. `is` is correct for comparing against singletons like `None` (`x is None`, not `x == None`), since there is exactly one `None` object and identity is the more precise, idiomatic check.

Python Web Frameworks Overview

Why does the choice between WSGI and ASGI matter when picking a Python web framework?

WSGI (Web Server Gateway Interface) is the traditional, synchronous interface between Python web applications and servers, one request is handled by one worker thread/process at a time, blocking for its duration. ASGI (Asynchronous Server Gateway Interface) extends that to support async request handling and other async protocols (WebSockets), letting a single worker handle many concurrent requests while they're waiting on I/O, the same underlying model as asyncio generally. Flask and Django historically are WSGI (Django has gained ASGI support); FastAPI is ASGI-native. The choice matters because it determines whether the framework can actually benefit from async I/O concurrency, or whether it's fundamentally a one-request-per-worker model regardless of async syntax used inside a handler.

Recursion & the Call Stack

What does Python's recursion limit actually protect against, and is it just an arbitrary language-level rule?

It protects the real, underlying C stack the Python interpreter itself runs on, each level of recursion consumes real stack memory, and without a limit, sufficiently deep (or infinite) recursion would exhaust that stack and crash the interpreter process entirely, a hard C-level failure, not a clean Python exception. The limit converts that hard crash into a catchable `RecursionError` raised well before the actual stack is exhausted, which is exactly why it exists, a controlled failure mode is far better than an uncontrolled process crash, not an arbitrary restriction on how "should" write code.

Sorting Algorithms & Stability

Why does Python's sort achieve O(n) in the best case rather than always costing O(n log n) like a textbook mergesort?

Python uses Timsort, which specifically looks for and exploits "runs," contiguous stretches of already-ordered (or reverse-ordered) elements already present in the input, merging those runs rather than treating the data as uniformly random. Fully-sorted input is the extreme case of this: it's already one giant run, so Timsort recognizes it and finishes in linear time instead of doing the full comparison work a naive O(n log n) sort would perform regardless of input order. This is exactly why Timsort performs so well on real-world data, which is very often partially sorted already, not uniformly random.

Algorithms

Hash Tables & the Hash/Equality Contract

Why two objects that compare equal but hash differently don't raise an error when used as a dict key, they just silently fail to find each other, and why that makes the __eq__/__hash__ contract one of the most dangerous ones to get wrong.

Algorithms

Recursion & the Call Stack

Why CPython's recursion limit exists to protect the real, platform-dependent C stack rather than being an arbitrary language rule, and why raising it too high can still crash the interpreter instead of just allowing deeper recursion. Verified against CPython 3.12; exact stack behavior, default limit, and crash mode are interpreter- and version-specific, not universal across every Python implementation.

Hash Tables & the Hash/Equality Contract

What is the required contract between equality and hashing for an object used as a dictionary key, and why does the hash table need it specifically?

The contract is one-directional but strict: if two objects compare equal, they must produce the same hash value. A hash table uses an object's hash to pick which bucket to look in, then uses equality only to confirm the exact match within that bucket, so if two equal objects hashed differently, a lookup for one would search the wrong bucket entirely and never even reach the equality check that would have confirmed the match. The hash doesn't have to be unique across unequal objects (collisions are expected and handled), it just has to agree for anything that compares equal, that's the one property the whole lookup mechanism depends on.

Hash Tables & the Hash/Equality Contract

A custom class defines __eq__ based on a value field but leaves __hash__ using default identity-based hashing. What actually goes wrong when you use an instance as a dict key?

In Python 3, simply defining `__eq__` without touching `__hash__` doesn't leave the old identity-based hash in place, Python automatically sets `__hash__` to `None` on that class, making instances unhashable, so using one as a dict key raises `TypeError` immediately rather than corrupting anything. This happens even if a parent class defines `__hash__`: overriding `__eq__` in a subclass sets that subclass's `__hash__` to `None` regardless of what the parent provides, ordinary inheritance does not carry the parent's hash forward. The silent, no-exception version of this bug only happens if the class explicitly keeps or re-supplies an identity-based `__hash__` alongside the value-based `__eq__` (e.g. `__hash__ = object.__hash__`, or, to retain a parent's hash on purpose, `__hash__ = Parent.__hash__`). In that case, two instances with the same value compare equal (`a == b` is `True`) but hash differently, and inserting under key `a` then looking up with an equal-but-distinct key `b` lands in the wrong hash bucket and returns nothing, because the hash mismatch never gave the lookup a chance to even check equality against the right entry.

Python Async Programming

How does asyncio achieve concurrency with a single thread?

asyncio runs an event loop that manages many coroutines cooperatively, a coroutine runs until it hits an `await` on an I/O operation, at which point it voluntarily yields control back to the event loop, which then runs another ready coroutine. While one coroutine is waiting on network I/O, the CPU isn't idle; the event loop is running other coroutines. This works because I/O waiting doesn't need the CPU at all; the concurrency comes from overlapping wait times, not from parallel execution, which is why it's a single thread the whole time and no locks are needed between coroutines.

Python Async Programming

Why does calling a blocking function inside an async function defeat the purpose of using asyncio?

A blocking call (synchronous file I/O, a synchronous HTTP request, `time.sleep`) occupies the single thread the event loop runs on, and unlike `await`, it does not yield control back, the entire event loop is frozen for the duration of that blocking call, so every other coroutine that could otherwise be making progress is stalled too. This is why async code requires async-compatible libraries throughout the I/O path; a single accidental blocking call anywhere in a hot path can silently serialize what was supposed to be concurrent work, and the bug often doesn't show up until real concurrent load exposes it.

Python Async Programming

When does asyncio actually help, and when is it not worth the added complexity?

asyncio helps specifically for I/O-bound workloads with many concurrent operations, handling thousands of simultaneous network connections, making many concurrent API calls, where most of the time is spent waiting, not computing. It does not help CPU-bound work at all, since the event loop is still single-threaded and a CPU-heavy coroutine blocks everything else exactly like any other blocking call; CPU-bound work needs `multiprocessing` or a separate process pool instead. For a workload with low concurrency or that's primarily CPU-bound, asyncio adds real complexity (colored functions, async-compatible libraries everywhere) without a corresponding benefit.

Python Data Structures

Why is checking membership with `in` fast on a set or dict but slow on a list?

Sets and dicts are implemented as hash tables, checking whether a value exists means computing its hash and looking up that bucket directly, an O(1) average-case operation regardless of how many items are stored. A list has no such index; checking membership means scanning entries one by one until a match is found or the list ends, an O(n) operation that gets slower as the list grows. For any code doing repeated membership checks against a growing collection, using a set instead of a list is often the single biggest easy performance fix available.

Python Data Structures

What is the practical difference between a list and a tuple, beyond mutability?

The most visible difference is that lists are mutable (items can be added, removed, or changed after creation) and tuples are immutable (fixed once created). That immutability has real consequences: tuples can be used as dictionary keys or set members because they're hashable, while lists cannot. Tuples also communicate intent, a fixed-size, heterogeneous grouping (like a coordinate pair) is usually a better fit for a tuple, while a variable-length, homogeneous collection is usually a better fit for a list, independent of whether mutation is actually needed.

Python Data Structures

Why can a list not be used as a dictionary key, but a tuple can?

Dictionary keys must be hashable, and hashability requires that an object's hash value never changes for the lifetime of the object, which in turn requires immutability, because a mutable object's contents (and therefore its logical value) could change after being used as a key, silently breaking the hash table's internal bucket placement. Lists are mutable, so Python makes them explicitly unhashable to prevent that class of bug. Tuples are immutable, so as long as every element they contain is also hashable, the tuple itself is hashable and safe to use as a dictionary key or set member.

Python Virtual Environments & Packaging

Why does installing packages globally (outside a virtual environment) cause problems across multiple projects?

A global Python installation has exactly one set of installed package versions shared by everything that uses it. Two projects needing different, incompatible versions of the same package (one needs `requests==2.28`, another needs `requests==2.31` for a bug fix it depends on) cannot both be satisfied globally, installing one breaks the other. A virtual environment gives each project its own isolated package set, so version requirements never conflict across projects, and a project's dependencies are fully reproducible independent of whatever else happens to be installed globally.

Python Virtual Environments & Packaging

What is the difference between requirements.txt and a lockfile, and why does it matter for reproducibility?

A typical `requirements.txt` often specifies loose version ranges (`requests>=2.28`), which means two installs at different times can resolve to different actual versions as new releases come out, not truly reproducible. A lockfile (like `poetry.lock` or `uv.lock`) pins the exact resolved version of every dependency and transitive dependency, so installing from it produces the identical dependency tree every time, on any machine. The distinction matters because a subtle bug caused by a transitive dependency's patch version can be nearly impossible to reproduce without a lockfile guaranteeing everyone has the exact same versions.

Python Virtual Environments & Packaging

What problem does a tool like Poetry or uv solve that pip and venv alone do not?

pip installs packages and venv creates isolated environments, but neither one manages the two together as a single reproducible workflow, nor do they resolve and lock a full dependency tree (including transitive dependencies) automatically. Tools like Poetry and uv combine environment creation, dependency resolution, lockfile generation, and package building into one workflow, similar to how npm or cargo work in other ecosystems, removing the manual, error-prone process of keeping a requirements file, a lockfile, and an environment all consistent with each other by hand.

Python Web Frameworks Overview

What is the core philosophical difference between Flask and Django?

Flask is a microframework; it provides routing and request/response handling and deliberately leaves everything else (ORM, admin panel, authentication, forms) to be chosen and added by the developer. Django is batteries-included; it ships with an ORM, an admin interface, an authentication system, and a forms library as an integrated whole, with strong conventions about how a project should be structured. Flask trades built-in structure for flexibility; Django trades flexibility for a consistent, fully-equipped starting point. Neither is strictly better, the right choice depends on whether a project benefits more from Django's conventions or needs the freedom to pick its own pieces.

Python Web Frameworks Overview

What does FastAPI provide that Flask does not, and what's the trade-off?

FastAPI is async-first (built on ASGI, not WSGI) and uses Python type hints to automatically generate request validation, serialization, and interactive OpenAPI documentation, a type-annotated function signature becomes both the API contract and its enforcement, with no separate schema to maintain by hand. The trade-off is that FastAPI assumes an async-first mental model and a type-hint-driven style throughout, which is a bigger shift for a team used to Flask's simpler, synchronous, un-opinionated style, and FastAPI has a smaller, younger ecosystem of plugins/extensions compared to Flask or Django's much longer history.

Search results for “python” | Cloud Tech by Victor