Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🟡 Advanced Python  ·  Lesson 30

Python Best Practices

In this lesson: Write clean, readable Python — PEP 8 naming, functions, comments, errors and common mistakes to avoid. In Hindi & English.

Why clean code matters

Code is read far more often than it is written – by your teammates, by interviewers, and by you six months later. Clean code has fewer bugs, is easier to change and makes a strong impression in GitHub portfolios and machine-coding rounds.

Before and after: one program, two styles

Python – before.py (works, but…)
import json
def f(d,t=[]):
    for i in range(len(d)):
        if d[i]['m']>=40 and d[i]['m']!=None:
            t.append(d[i]['n'])
    return t
x=json.loads('[{"n":"Asha","m":91},{"n":"Ravi","m":35}]')
print(f(x))
print(f(x))
['Asha'] ['Asha', 'Asha']

Look at the second line of output: the list grew to ["Asha", "Asha"] on the second call. That is the famous mutable default argument bug – t=[] is created once and shared by every call. The names f, d, t, m, n also hide what the code means.

Python – after.py (clean)
"""Find students who passed an exam."""
import json

PASS_MARKS = 40


def passed_students(results: list[dict], pass_marks: int = PASS_MARKS) -> list[str]:
    """Return names of students whose marks are at least pass_marks."""
    return [r["name"] for r in results if r.get("marks") is not None and r["marks"] >= pass_marks]


def main() -> None:
    results = json.loads('[{"name": "Asha", "marks": 91}, {"name": "Ravi", "marks": 35}]')
    print(passed_students(results))
    print(passed_students(results))


if __name__ == "__main__":
    main()
['Asha'] ['Asha']
ChangeWhy
Meaningful names (passed_students, results)Code explains itself
Constant PASS_MARKSNo “magic numbers”; one place to change
No mutable default; build a new listFixes the hidden bug
Comprehension instead of range(len())Shorter and clearer
is not NoneCorrect way to compare with None
Type hints and docstringEditors and teammates know what goes in and out
main() + if __name__ == "__main__"File can be imported without running

PEP 8 naming and layout

ThingStyleExample
Variable, functionsnake_casetotal_fees, send_email()
ClassPascalCaseStudentReport
ConstantUPPER_SNAKEMAX_RETRIES = 3
Private helperleading underscore_clean_name()
Indentation4 spaces, never tabs
Line length79–100 characters (team choice)
Importstop of file: standard library, third-party, your modules

Pythonic habits

Python – pythonic.py
students = ["Asha", "Ravi", "Neha"]
marks = [91, 58, 76]

# 1. enumerate instead of range(len())
for rank, name in enumerate(students, start=1):
    print(rank, name)

# 2. zip to walk two lists together
report = {name: m for name, m in zip(students, marks)}
print(report)

# 3. f-strings with formatting
fee = 12500.5
print(f"Fee: ₹{fee:,.2f} | Pass rate: {2/3:.0%}")

# 4. truthiness instead of len(x) == 0
pending = []
if not pending:
    print("No pending fees")

# 5. dict.get with a default
print(report.get("Kabir", "absent"))

# 6. unpacking
first, *others = students
print(first, others)
1 Asha 2 Ravi 3 Neha {'Asha': 91, 'Ravi': 58, 'Neha': 76} Fee: ₹12,500.50 | Pass rate: 67% No pending fees absent Asha ['Ravi', 'Neha']

Resources: always use with

Python – with_files.py
# bad: file stays open if an error happens before close()
f = open("notes.txt", "w", encoding="utf-8")
f.write("Revise loops\n")
f.close()

# good: closed automatically, even on errors
with open("notes.txt", "a", encoding="utf-8") as f:
    f.write("Practise functions\n")

with open("notes.txt", encoding="utf-8") as f:
    print(f.read().strip())
Revise loops Practise functions

Handle errors specifically

Python – specific_errors.py
def read_age(text):
    try:
        age = int(text)
    except ValueError:                    # catch only what you expect
        return None
    if not 5 <= age <= 100:
        raise ValueError(f"age {age} out of range")
    return age

print(read_age("15"), read_age("fifteen"))
try:
    read_age("150")
except ValueError as e:
    print("Error:", e)
15 None Error: age 150 out of range
⚠️ Never write bare except

except: or except Exception: pass hides real bugs (even typos and Ctrl+C). Catch the specific exception you can handle, and log or re-raise the rest.

Small functions with one job

  • A function should do one thing and be explainable in one sentence.
  • Prefer returning values over printing inside functions – returned values can be tested and reused.
  • Avoid global variables; pass data in as arguments.
  • More than 4–5 parameters? Group them in a dataclass or dict.
  • Use keyword arguments for clarity: send(to="riya", retry=True).
Python – dataclass.py
from dataclasses import dataclass

@dataclass
class Order:
    item: str
    price: float
    qty: int = 1

    @property
    def total(self) -> float:
        return self.price * self.qty

o = Order("Kaju Katli", 900, 2)
print(o)
print(o.total)
Order(item='Kaju Katli', price=900, qty=2) 1800

Let tools check your style

ToolJobCommand
ruffVery fast linter: finds unused imports, bugs, style issuesruff check .
black / ruff formatFormats code automaticallyruff format .
mypyChecks type hintsmypy app.py
pytestRuns testspytest

Running ruff on the “before” program finds problems automatically:

Python – before.py → ruff check --select E,F,B before.py
import json
def f(d,t=[]):
    for i in range(len(d)):
        if d[i]['m']>=40 and d[i]['m']!=None:
            t.append(d[i]['n'])
    return t
x=json.loads('[{"n":"Asha","m":91},{"n":"Ravi","m":35}]')
print(f(x))
print(f(x))
before.py:2:11: B006 Do not use mutable data structures for argument defaults before.py:4:41: E711 Comparison to `None` should be `cond is not None` Found 2 errors. 2 unsafe fixes available with `--fix --unsafe-fixes`.

Code review checklist

  1. Names explain purpose; no single letters except tiny loops.
  2. No duplicated code – repeated logic moved into a function.
  3. No magic numbers – named constants.
  4. Errors handled specifically; no bare except.
  5. Files and connections opened with with.
  6. Functions are short, return values, have docstrings for public use.
  7. Tests exist for the important rules.
  8. ruff shows no warnings; code is formatted.

Practice tasks

  1. Take one of your old programs and rename every variable to a meaningful name.
  2. Find and fix a mutable default argument in a function that collects items.
  3. Install ruff in a venv, run ruff check . on a project and fix every warning.
  4. Convert a dictionary-based record into a dataclass with a computed property.

Summary

  • Follow PEP 8 names: snake_case, PascalCase, UPPER_SNAKE.
  • Never use a mutable default argument such as [] or {}.
  • Use enumerate, zip, f-strings, with, comprehensions and specific exceptions.
  • Small functions, type hints, docstrings, main() guard.
  • Automate style with ruff/black and correctness with pytest.

Frequently Asked Questions

Are type hints required in Python?
No. Python ignores them at runtime. They help editors, linters, mypy and teammates understand your code, so they are standard in professional projects.
Should I use black or ruff format?
Both produce almost the same style. ruff format is much faster and the same tool also lints, so many new projects use ruff for both jobs.
← Back to Python Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicPython Mini Projects Your progress: 30 / 66 (45%) · Lesson 31 / 66 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free