Add tech_docs/python/python_deep_dive.md
This commit is contained in:
106
tech_docs/python/python_deep_dive.md
Normal file
106
tech_docs/python/python_deep_dive.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
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:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **1. Python Naming Conventions: Double Underscore and Privacy**
|
||||||
|
|
||||||
|
### A. **Dunder (Double-Underscore) Methods**
|
||||||
|
- **Purpose**: Special system-defined methods that control object behavior with built-in functions and operators.
|
||||||
|
- **Examples**:
|
||||||
|
- `__init__()` – Constructor for initializing an object.
|
||||||
|
- `__len__()` – Defines length for `len()` function.
|
||||||
|
- `__str__()` – Controls string representation with `str()`.
|
||||||
|
- **Usage**: You implement these methods to define or customize how objects interact with common Python operations.
|
||||||
|
|
||||||
|
### B. **Single Leading Underscore (_name) – Protected Attributes**
|
||||||
|
- **Convention**: Used to indicate **protected** attributes or methods meant for internal use.
|
||||||
|
- **Access**: Accessible both within and outside the class, but it’s **discouraged** to access from outside.
|
||||||
|
- **Usage**: Use `_name` to signal that an attribute or method should be treated as internal, though not strictly enforced.
|
||||||
|
|
||||||
|
### C. **Double Leading Underscore (__name) – Private Attributes**
|
||||||
|
- **Purpose**: Used to mark attributes as **private** and avoid accidental access, especially in subclasses.
|
||||||
|
- **Name Mangling**: Python renames `__name` to `_ClassName__name` to prevent accidental overrides.
|
||||||
|
- **Access**: Not intended for external access, though it can still be accessed using the mangled name.
|
||||||
|
- **Usage**: Use `__name` when you want to ensure that an attribute is not easily overridden in subclasses.
|
||||||
|
|
||||||
|
### D. **Double Leading and Trailing Underscore (__name__) – Reserved System Methods**
|
||||||
|
- **Purpose**: Reserved for Python's system-defined methods and attributes.
|
||||||
|
- **Examples**:
|
||||||
|
- `__init__()`, `__call__()`, `__str__()`
|
||||||
|
- **Usage**: Avoid using this pattern in your own code unless you’re overriding a special method.
|
||||||
|
|
||||||
|
### E. **Single Trailing Underscore (name_)**
|
||||||
|
- **Purpose**: Used to avoid conflicts with Python keywords (e.g., `class_`, `def_`).
|
||||||
|
- **Usage**: Use it to avoid naming collisions when naming attributes or variables that would otherwise conflict with reserved words.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **2. Name Mangling in Python**
|
||||||
|
|
||||||
|
### A. **Definition**
|
||||||
|
- **What It Is**: A process that alters the name of attributes with **double leading underscores** (`__name`) to include the class name (`_ClassName__name`).
|
||||||
|
- **Purpose**: Prevents accidental overriding or access of private attributes from subclasses.
|
||||||
|
|
||||||
|
### B. **Example**
|
||||||
|
```python
|
||||||
|
class Parent:
|
||||||
|
def __init__(self):
|
||||||
|
self.__private_var = 42 # Becomes _Parent__private_var
|
||||||
|
```
|
||||||
|
- You can't access `__private_var` directly from outside the class, but can still access it using the mangled name (`_Parent__private_var`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **3. Differences Between Private and Protected Attributes**
|
||||||
|
|
||||||
|
### A. **Protected (_name)**
|
||||||
|
- **Convention**: Attribute is for internal use but still accessible from outside.
|
||||||
|
- **Access**: Meant for access within the class and its subclasses, though not strictly enforced.
|
||||||
|
- **Example**:
|
||||||
|
```python
|
||||||
|
class MyClass:
|
||||||
|
def __init__(self):
|
||||||
|
self._protected_var = 10
|
||||||
|
```
|
||||||
|
|
||||||
|
### B. **Private (__name)**
|
||||||
|
- **Convention**: Attribute is more "private" and is **name-mangled** to avoid accidental access or override.
|
||||||
|
- **Access**: Can only be accessed via name mangling (e.g., `_ClassName__name`).
|
||||||
|
- **Example**:
|
||||||
|
```python
|
||||||
|
class MyClass:
|
||||||
|
def __init__(self):
|
||||||
|
self.__private_var = 42 # Becomes _MyClass__private_var
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **4. Summary Table of Usage**
|
||||||
|
|
||||||
|
| **Type** | **Notation** | **Intended Usage** | **Enforced by Python?** |
|
||||||
|
|----------------------------|---------------------------|-----------------------------------------------------------------|----------------------------------------|
|
||||||
|
| **Dunder (Special)** | `__init__()`, `__len__()` | Special methods to control behavior of built-in operations. | Yes, by system convention. |
|
||||||
|
| **Protected** | `_name` | Internal use; accessible from outside but discouraged. | No, it's a convention. |
|
||||||
|
| **Private (Name Mangling)** | `__name` | Name-mangled to avoid accidental access or overriding. | Somewhat, by name mangling. |
|
||||||
|
| **Reserved System Methods** | `__name__` | Python-reserved methods and attributes. | Yes, reserved for system use. |
|
||||||
|
| **Avoid Conflicts** | `name_` | Used to avoid conflicts with reserved keywords. | No, it's a naming convention. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **5. Practical Applications and Recommendations**
|
||||||
|
|
||||||
|
### A. **When to Use Protected (`_name`)**:
|
||||||
|
- **Internal Attributes**: Use `_name` when you want to signal to other developers that an attribute or method is **internal** but may be accessed in subclasses.
|
||||||
|
- **Not Strict**: It's a convention, so it’s not strongly enforced. Other developers can still access these if they need to.
|
||||||
|
|
||||||
|
### B. **When to Use Private (`__name`)**:
|
||||||
|
- **Avoiding Subclass Conflicts**: Use `__name` if you want to avoid accidental overrides in subclasses.
|
||||||
|
- **More Private**: This adds a layer of protection, making it harder to access or override. However, it's still accessible through name mangling if necessary.
|
||||||
|
|
||||||
|
### C. **When to Use Dunder Methods (`__init__`, `__str__`, etc.)**:
|
||||||
|
- **Customizing Behavior**: Use dunder methods to customize how your class instances interact with Python’s built-in functions (e.g., `len()`, `str()`, `+`, `==`).
|
||||||
|
- **Keep It Simple**: Don’t define your own names with leading and trailing double underscores unless you're overriding one of Python’s special methods.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This outline provides you with a structured way to understand and track how and when to use double underscores and underscores in Python. Let me know if you want further clarifications on any section!
|
||||||
Reference in New Issue
Block a user