Jiaxi Liu (Jesse)

Master’s Graduate

Software Engineer | Scalable APIs · Web Scraping · Data Integration · Code Quality & Refactoring

Back to Blog

Python and Flask Review: Decorators, Generators, Copying, Magic Methods, Encryption, and Tokens

Python fundamentals often appear in backend interviews and automation scripting.

Decorators

A decorator is a function that takes a function and returns a new function.

def log(fn):
    def wrapper(*args, **kwargs):
        print("before")
        result = fn(*args, **kwargs)
        print("after")
        return result
    return wrapper
 
@log
def hello():
    print("hello")

@log is equivalent to hello = log(hello).

Generators

Generators use yield and produce values lazily.

def count():
    yield 1
    yield 2
 
for item in count():
    print(item)

They are useful for large data streams because they avoid loading everything at once.

Shallow Copy and Deep Copy

Shallow copy copies only the first level. Nested references are still shared. Deep copy recursively copies nested objects.

import copy
 
a = [[1], [2]]
b = copy.copy(a)
c = copy.deepcopy(a)

Magic Methods

Common magic methods:

  • __init__: initialize an object
  • __new__: create an object
  • __del__: called when an object is destroyed
  • __str__: string representation

Flask, Encryption, and Tokens

Flask is a lightweight Python web framework. A common token authentication flow:

  1. User logs in
  2. Server verifies credentials
  3. Server returns a token
  4. Later requests include the token
  5. Server validates the token and returns resources

In real systems, use HTTPS, expiration, and permission checks.

Deeper Notes

When reviewing this topic, do not memorize names only. Focus on decorators, generators, copy semantics, magic methods, Flask routing, encryption, and tokens. If this stays at the definition level, it becomes hard to explain in interviews or apply in projects. A stronger way to study it is to place it in a concrete scenario: who calls it, where the input comes from, what happens on failure, and whether data or state can be processed twice.

  • Backend design is not just making endpoints work; authentication, validation, errors, idempotency, logs, and versioning need clear places.
  • API fields should express business meaning instead of directly exposing table structure.
  • When reviewing an API, check success, authorization failure, invalid input, missing resources, and dependency failure.

In a real project, use it as a decision framework: identify inputs, constraints, failure modes, and observability before choosing a specific tool or pattern. If a solution looks simple, keep asking whether it still works when scale grows, permissions change, recovery matters, and more people collaborate on it.

Practical Checklist

  • Identify where this concept sits in the system: development-time constraint, runtime behavior, infrastructure capability, or collaboration workflow.
  • Write one minimal working example and one failure example; only knowing the happy path is usually not enough.
  • Record common misuses: edge cases, permission assumptions, performance assumptions, sync/async differences, or environment differences.
  • Connect the concept to a project experience so that an interview answer can be grounded in real tradeoffs.
  • End with one sentence about tradeoff: what it gives up and what it buys.

Self-Check Questions

  1. What core problem does this topic solve?
  2. What alternatives exist, and what are their costs?
  3. Where are the most likely edge cases?
  4. How would code, tests, or monitoring prove that it is reliable?

Applied Scenario

A concrete way to study this topic is a user or content management system. The frontend submits a form; the backend authenticates the caller, checks permission, validates input, runs business logic, and returns stable status codes and error shapes. A mature backend endpoint must cover token expiration, missing permission, duplicate submission, invalid input, database failure, and dependency timeout. Documentation, logs, monitoring, and tests should all be built around these paths.

Common Pitfalls:

  • Mixing up authentication and authorization.
  • Only validating on the frontend and trusting incoming requests.
  • Returning 500 for every error, making recovery impossible for callers.