diff --git a/tech_docs/python/python_deep_dive.md b/tech_docs/python/python_deep_dive.md index a027f2f..bbb48fa 100644 --- a/tech_docs/python/python_deep_dive.md +++ b/tech_docs/python/python_deep_dive.md @@ -1,3 +1,52 @@ +Sure! Let’s break it down into simpler, more digestible pieces: + +### 1. **Double Underscore Methods (Dunder Methods)** +These are special methods in Python that have **two underscores** on each side, like `__init__()`. Python uses them automatically for specific operations, so you don’t normally call them directly. + +- **Examples**: + - `__init__()` is used when you create a new instance of a class (like a constructor). + - `__len__()` is used when you call `len()` on an object. + +These methods let you customize how objects behave with Python’s built-in functions. + +### 2. **Single Leading Underscore (_name)** +A **single underscore** at the start of a name (e.g., `_name`) is a **convention** to say, "Hey, this is internal! Don’t mess with it unless you really need to." It’s like a "soft privacy" signal to other programmers. + +- **Example**: If you see `_internal_data`, it’s not strictly private, but it’s meant to be used internally within the class or module. + +### 3. **Double Leading Underscore (__name)** +A **double underscore** at the start of a name (e.g., `__name`) triggers **name mangling**. This means Python changes the name behind the scenes to avoid conflicts in subclasses. It’s a way to prevent accidental name collisions. + +- **Example**: If you define `__private_var` in a class, Python will rename it to something like `_ClassName__private_var`, making it harder to accidentally override it in subclasses. + +### 4. **Double Leading and Trailing Underscore (__name__)** +If something has **double underscores on both sides**, like `__init__` or `__len__`, it’s a **special system method** that Python uses. Don’t name your own methods like this unless you’re overriding a built-in method on purpose. + +- **Example**: Python already has a method like `__str__()` that defines how an object is printed. You can customize this in your own class to change how it looks when printed. + +### 5. **Single Trailing Underscore (name_)** +When you see a **single trailing underscore** (e.g., `class_`), it’s used to avoid conflicts with Python’s reserved words or built-in functions. + +- **Example**: `class` is a reserved keyword in Python, so if you need a variable with that name, you can use `class_` instead. + +### 6. **No Underscore (Public Names)** +If a name has **no underscores**, like `name`, it’s just a regular attribute or method, and it’s intended for public use. + +- **Example**: `self.name = "John"` in a class means that anyone using this class can access the `name` attribute. + +### How To Use This: + +- If you see a method with `__double_underscores__`, it’s special and built into Python. +- Use a single leading underscore `_name` to tell others, "This is internal! Handle with care." +- Use double leading underscores `__name` when you want to protect something from being easily overridden in a subclass. +- Avoid naming anything with double underscores on both sides unless you're overriding a special behavior. + +--- + +Does this help clarify things? Let me know if any part is still unclear! + +--- + Certainly! Here's a clear **outline** that summarizes the key concepts we've discussed. You can use this as a reference to track these important items: ---