8 Python Tricks That Can Save You 30 Minutes Every Day
This article presents eight practical Python techniques—from using python -m to avoid import errors, to pathlib for path handling, dataclasses for boilerplate reduction, rich for pretty debugging, enumerate, proper __main__ guards, perf_counter for accurate timing, and watchdog for hot‑reloading—each designed to eliminate daily friction and boost development efficiency.
TL;DR
Small frictions like frequent ImportError, manual __init__, and os.path path joins waste more time than algorithmic gaps.
All eight tricks rely only on the Python standard library or a single pip install, requiring no new frameworks or project refactoring.
Using python -m, pathlib, dataclass, and rich frees mental resources for higher‑value problems.
Effect First
Most beginners write code like this:
import os
# manual path join, ugly and error‑prone
data_dir = os.path.join("project", "data", "2024", "raw")
config_file = os.path.join(data_dir, "config.json")
# manual counter
i = 0
items = ["requests", "httpx", "aiohttp"]
for item in items:
print(f"{i}: {item}")
i += 1
# hand‑written __init__
class APIConfig:
def __init__(self, url, timeout, retries):
self.url = url
self.timeout = timeout
self.retries = retries
def __repr__(self):
return f"APIConfig(url={self.url}, timeout={self.timeout}, retries={self.retries})"After applying the tricks:
from pathlib import Path
data_dir = Path("project") / "data" / "2024" / "raw"
config_file = data_dir / "config.json"
items = ["requests", "httpx", "aiohttp"]
for i, item in enumerate(items):
print(f"{i}: {item}")
from dataclasses import dataclass
@dataclass
class APIConfig:
url: str
timeout: int
retries: intThe rewritten version is roughly half the size and more readable.
Scenario Definition
After four years of Python development, the author observed that the real speed killers are not missing algorithms but a collection of "small annoyances" that appear dozens of times per day, such as ImportError, unreadable debug output, hand‑written __init__, and os.path path joins.
Environment Setup
All examples target Python 3.9+, though most features work on 3.7+. The only external dependency is rich: pip install rich Everything else is in the standard library.
Core Tricks
Trick 1: Use python -m to Run Scripts and Avoid Import Errors
Running a script with python app/main.py often triggers
ImportError: attempted relative import with no known parent package. Executing it as a module— python -m app.main —makes Python treat the code as a proper module, aligning import paths automatically.
I once saw an intern waste two hours debugging this error; a single command change fixed it.
Trick 2: Use rich for Pretty Debug Output
Standard print() is functional but ugly for nested structures. rich adds syntax highlighting and indentation automatically.
from rich import print
data = {"user": "小王", "requests": 142, "errors": [{"code": 503, "msg": "Service Unavailable", "count": 12}, {"code": 429, "msg": "Rate Limited", "count": 7}]}
print(data)Adding from rich.traceback import install; install() turns all tracebacks into colored, layered output, reducing cognitive load during debugging.
Trick 3: Replace os.path with pathlib
Legacy code often uses os.path.join(...) and open(). pathlib provides an object‑oriented, slash‑based syntax and built‑in helpers like read_text(), write_text(), and glob().
from pathlib import Path
config_path = Path("project") / "config" / "app.yaml"
if config_path.exists():
content = config_path.read_text()Using / for path concatenation feels far more natural than os.path.join().
Trick 4: Use dataclasses to Eliminate Boilerplate
When a class only stores data, a @dataclass automatically generates __init__, __repr__, and __eq__ in three lines.
from dataclasses import dataclass
@dataclass
class LLMConfig:
model: str = "claude-sonnet-4-6"
temperature: float = 0.7
max_tokens: int = 4096This is especially handy in API development, configuration management, and ETL pipelines.
Trick 5: Use enumerate() and List Comprehensions
Instead of manually managing an index:
i = 0
for name in names:
print(i, name)
i += 1Python’s enumerate() does it in one line:
for i, name in enumerate(names):
print(i, name)Similarly, replace a four‑line mapping loop with a single‑line list comprehension, but avoid deep or overly complex comprehensions—if they become unreadable, revert to a plain loop.
Trick 6: Guard the Entry Point with if __name__ == "__main__"
Encapsulating script logic in a main() function and protecting it with the guard prevents accidental execution when the file is imported elsewhere, which could otherwise trigger unwanted API calls, DB writes, or emails.
def main():
process_data()
generate_report()
if __name__ == "__main__":
main()Missing the guard can lead to night‑time alerts caused by unintended side effects.
Trick 7: Use time.perf_counter() for Accurate Benchmarks
time.time()is unsuitable for benchmarking because of low precision and susceptibility to system clock changes. perf_counter() offers high‑resolution, monotonic timing.
from time import perf_counter
start = perf_counter()
# ... code to benchmark ...
elapsed = perf_counter() - start
print(f"耗时: {elapsed:.4f} 秒")This precision matters when optimizing API responses or data pipelines that run hundreds of thousands of times.
Trick 8: Use watchdog for Hot Reloading
Install watchdog and run:
pip install watchdog
watchmedo auto-restart --patterns="*.py" -- python your_script.pySaving a file now automatically restarts the script, turning the edit‑run‑repeat cycle into a seamless experience.
Pitfalls & Reminders
When using python -m, separate modules with dots, not slashes (e.g., app.main).
Avoid mutable default values in dataclass fields; use field(default_factory=list) instead.
Keep list comprehensions shallow—more than two nested levels or complex if clauses should be rewritten as loops. perf_counter() returns seconds relative to an arbitrary start; use it only for differences.
Full Template & Next Steps
A ready‑to‑use daily‑script template combines all tricks:
"""Daily Python script template – start every new project here"""
from pathlib import Path
from time import perf_counter
from dataclasses import dataclass
from rich import print
from rich.traceback import install
install() # global pretty traceback
@dataclass
class Config:
data_dir: str = "data"
output_dir: str = "output"
def process_files(config: Config) -> list[Path]:
"""Read all CSV files under data_dir and return their paths"""
data_path = Path(config.data_dir)
if not data_path.exists():
raise FileNotFoundError(f"目录不存在: {config.data_dir}")
return list(data_path.glob("*.csv"))
def main():
start = perf_counter()
config = Config()
files = process_files(config)
for i, f in enumerate(files):
print(f"[{i}] {f.name}")
print(f"
[green]处理完成,共 {len(files)} 个文件,耗时 {perf_counter() - start:.3f}s[/green]")
if __name__ == "__main__":
main()Save this as a starter, then consider extending it with rich.progress for progress bars, watchdog for directory watching, or swapping dataclasses for pydantic.BaseModel to add validation.
Each tiny improvement—fewer bugs, less boilerplate, lower cognitive load—accumulates into a noticeable productivity boost over weeks and months.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Data STUDIO
Click to receive the "Python Study Handbook"; reply "benefit" in the chat to get it. Data STUDIO focuses on original data science articles, centered on Python, covering machine learning, data analysis, visualization, MySQL and other practical knowledge and project case studies.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
