Pythonic Idioms & Best Practices

PEP 8, PEP 20 — Python সম্প্রদায়ের সম্মিলিত জ্ঞান

Read: ~25 min Intermediate 5 practice problems Live code runner

1. What Does "Pythonic" Mean?

Python has a distinct aesthetic. Code that reads naturally, uses built-in features instead of reinventing them, and follows community conventions is called Pythonic. Two documents guide that aesthetic: PEP 8 (the style guide) and PEP 20 (The Zen of Python). Mastering them is the difference between "someone who knows Python syntax" and "a Pythonista".

Python-এর একটি নিজস্ব aesthetic আছে। যে কোড সাবলীলভাবে পড়া যায়, built-in feature ব্যবহার করে চাকা পুনরাবিষ্কার করে না, এবং community convention অনুসরণ করে — সেটিকে Pythonic বলা হয়। এই নান্দনিকতার দুই গাইড: PEP 8 (style guide) ও PEP 20 (Zen of Python)।

2. The Zen of Python (PEP 20)

zen.py
import this

Key lines to internalize:

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Readability counts.
  • Errors should never pass silently.
  • There should be one — and preferably only one — obvious way to do it.
  • Now is better than never.

3. PEP 8 — The Style Guide Essentials

RuleExample
4-space indentation, no tabs return x
Line length ≤ 79 (or 88 for black)Wrap long lines with \ or parens
Variables and functions in snake_caseuser_count, get_user()
Classes in PascalCaseclass UserAccount:
Constants in UPPER_CASEMAX_RETRIES = 5
Two blank lines between top-level defs—
One blank line between methods—
Spaces around binary operatorsx = a + b
No trailing whitespaceYour editor should strip it

4. Pythonic vs Not — Concrete Comparisons

idioms.py
items = ["rice", "dal", "fish"]

# Iteration — not this:
# for i in range(len(items)):
#     print(items[i])
# do this:
for item in items:
    print(item)

# With index — not this:
# i = 0
# for item in items:
#     print(i, item); i += 1
# do this:
for i, item in enumerate(items):
    print(i, item)

# Emptiness — not this:
# if len(items) == 0:
# do this:
if not items:
    print("empty")

# Swap — use tuple packing:
a, b = 1, 2
a, b = b, a
print(a, b)

# Joining strings — not a + b + c loop:
print(", ".join(items))

5. Formatters & Linters — Set and Forget

  • black — an opinionated formatter. Zero options. Run it on save.
  • ruff — a fast linter (written in Rust). Replaces flake8, pylint, isort, and more.
  • isort — sorts imports (often integrated into ruff now).
  • mypy — static type checker (Module 28).
Workflow: install black and ruff, enable "format on save" in your editor, add them to your pre-commit hooks. You will never argue about tabs again.

6. Anti-Patterns to Avoid

  • Mutable default arguments: def f(x, items=[]) shares the list across calls. Use items=None and create inside.
  • Catching bare except: — it hides KeyboardInterrupt and bugs. Catch specific exceptions.
  • Over-using global: pass arguments or wrap in a class instead.
  • Deep nesting: use early returns, guard clauses, or helpers.
  • Ambiguous names: tmp, data, x, foo — name the meaning, not the shape.
  • Reinventing stdlib: always check collections, itertools, functools first.

7. Vocabulary (শব্দভাণ্ডার)

TermMeaningবাংলায়
PEPPython Enhancement Proposal — a design doc.Python-এর একটি আনুষ্ঠানিক design document।
PythonicIdiomatic Python style.Python-এর স্বাভাবিক শৈলী।
FormatterTool that rewrites code for style.কোডকে স্টাইল অনুযায়ী পুনর্লিখন করার tool।
LinterTool that finds potential issues.সম্ভাব্য সমস্যা খুঁজে বের করার tool।
Anti-patternA pattern that looks useful but causes bugs.দেখে উপকারী মনে হলেও bug তৈরি করে এমন pattern।

8. Practice Problems

  1. Rewrite for i in range(len(items)): print(items[i]) the Pythonic way.
    উপরের কোডটিকে Pythonic-ভাবে লিখুন।
    ✨ Show Answer (উত্তর দেখুন)
    ans1.py
    items = ["a", "b", "c"]
    for item in items:
        print(item)
  2. Spot the bug: def add_to(x, lst=[]): lst.append(x); return lst. Explain and fix.
    বাগটি খুঁজুন: def add_to(x, lst=[])... ব্যাখ্যা ও সমাধান দিন।
    ✨ Show Answer (উত্তর দেখুন)

    Bug: The default [] is created once at function-definition time and reused across calls, so each call appends to the same list.

    Fix:

    ans2.py
    def add_to(x, lst=None):
        if lst is None:
            lst = []
        lst.append(x)
        return lst
    
    print(add_to(1))
    print(add_to(2))
  3. Name the PEP 8 casing for: variable, function, class, constant.
    PEP 8 অনুযায়ী casing বলুন — variable, function, class, constant-এর জন্য।
    ✨ Show Answer (উত্তর দেখুন)

    variable/function → snake_case; class → PascalCase; constant → UPPER_CASE; modules/packages → lowercase (short, all-lowercase).

  4. Rewrite if len(s) > 0: the idiomatic way.
    if len(s) > 0:-কে idiomatic-ভাবে লিখুন।
    ✨ Show Answer (উত্তর দেখুন)
    ans4.py
    s = "hello"
    if s:
        print("non-empty")
  5. Explain in one sentence what "Explicit is better than implicit" means practically.
    "Explicit is better than implicit" — এর ব্যবহারিক অর্থ এক বাক্যে লিখুন।
    ✨ Show Answer (উত্তর দেখুন)

    It means code should state what it does without hidden magic — prefer clearly named variables and explicit imports over from x import * or globally configured behavior — because later readers (including future you) should not have to search to find why something works.

    কোডের কাজটি লুকানো জাদু ছাড়াই স্পষ্টভাবে দেখানো উচিত — from x import * বা global configuration-এর চেয়ে নামকরা variable ও explicit import ভালো — কারণ ভবিষ্যতের পাঠকের (বা ভবিষ্যৎ আপনার) কিছু খুঁজে বের করতে না হওয়াই কাম্য।

Summary — Module 30

Pythonic code is readable, idiomatic, and respects conventions. Read PEP 8 and PEP 20 at least once — then forget the details and let tools (black, ruff, mypy) enforce them. Pick clear names, iterate over iterables directly, trust truthiness, and rely on the standard library before writing your own utilities.

Pythonic কোড পাঠযোগ্য, idiomatic, ও convention-সম্মত। PEP 8 ও PEP 20 একবার পড়ুন — তারপর detail ভুলে যান, tool-দের (black, ruff, mypy) দিয়ে enforce করান।

Next Module → Performance: Profiling & Optimization।