۹ قابلیت پایتون که اتوماسیون رو شیک و تمیز میکنه
۹ قابلیت مخفی پایتون که کدنویسی اتوماسیون رو سادهتر، تمیزتر و سریعتر میکنن. برای برنامهنویسها و علاقهمندان اتوماسیون.

اگه مدتیه با پایتون کارهای تکراری و روزمره رو اتومات کردی، احتمالاً کلی اسکریپت نوشتی که میشه گفت: «کار میکنه، ولی دست بهش نزن!» 😅
این اسکریپتها کار رو راه میندازن، اما یک سال بعد که برگردی سراغشون، بیشتر شبیه به یه بشقاب ماکارونی بههمریخته شدن تا یه کد خوشگل و مرتب.
راز اینکه اسکریپتهات هم تمیز بمونه و هم قابل نگهداری باشه، همیشه نصب کردن یه کتابخونه جدید نیست. خیلی وقتا همون قابلیتهای کمتر دیدهشدهی خود پایتون، نجاتدهنده هستن.
اینجا ۹ تا از اون قابلیتها رو آوردم که باعث میشن کدهای اتوماسیونت سریعتر، قابل اعتمادتر و از همه مهمتر تمیزتر باشن.
1. عملیات اتمیک با pathlib
دیگه فراموش کن os.path
و رشتهسازی دستی مسیرها رو. با pathlib
همهچیز شیءگرا میشه و حتی عملیات اتمیک هم داری که جلوی فایلهای نصفهنیمه رو میگیره.
from pathlib import Path
data = Path('reports') / 'daily.csv'
data.parent.mkdir(parents=True, exist_ok=True) # auto-create dirs
tmp = data.with_suffix('.tmp')
tmp.write_text('some,data,here')
tmp.replace(data) # atomic move to final file
چرا جذابه؟
هیچوقت فایل ناقص نمیذاره اگه اسکریپت وسط کار کرش کنه. برای کرونجابها خیلی عالیه.
2. functools.cached_property
(پایتون 3.8 به بعد)
یه محاسبه سنگین یا عملیات I/O داری که فقط یکبار لازمش داری؟ دیگه لازم نیست خودت منطق Cache رو پیادهسازی کنی.
from functools import cached_property
import requests
class WeatherClient:
def __init__(self, city):
self.city = city
@cached_property
def data(self):
return requests.get(f'https://wttr.in/{self.city}?format=j1').json()
client = WeatherClient('London')
print(client.data['current_condition'])
چرا جذابه؟
یه بار اجرا میشه و بعدش همیشه آمادهست. هیچ ساختار Cache اضافه هم لازم نداری.
3. مدیریت داینامیک منابع با contextlib.ExitStack
تا حالا شده بخوای تعدادی فایل همزمان رو باز کنی؟ با with
های تو در تو کد خیلی زشت میشه. اینجا ExitStack
به کمکت میاد.
from contextlib import ExitStack
files = ['a.txt', 'b.txt', 'c.txt']
with ExitStack() as stack:
handles = [stack.enter_context(open(f)) for f in files]
data = [h.read() for h in handles]
چرا جذابه؟
یه with
کافیه برای هر تعداد منبع. کدت تمیز میمونه و نیاز به with
تو در تو نیست.
4. موازیسازی با فیدبک لحظهای
خیلیا ThreadPoolExecutor
رو میشناسن، ولی کمتر کسی میدونه as_completed
میتونه نتایج رو همون لحظهای که آماده شدن بهت برگردونه.
from concurrent.futures import ThreadPoolExecutor, as_completed
import requests
urls = ['https://example.com', 'https://python.org', 'https://pypi.org']
with ThreadPoolExecutor(max_workers=5) as ex:
futures = [ex.submit(requests.get, url) for url in urls]
for future in as_completed(futures):
print(f"{future.result().url} done")
چرا جذابه؟
فیدبک فوری میگیری. برای مثال در کد بالا لازم نیست تا آخرین URL صبر کنی.
5. پاکسازی خودکار - tempfile.TemporaryDirectory
خیلی وقتا وسط اتوماسیون باید فایل موقت بسازی. چرا بذاری یه عالمه فایل بی استفاده روی سیستم بمونه؟
import tempfile, shutil, pathlib
with tempfile.TemporaryDirectory() as tmpdir:
path = pathlib.Path(tmpdir) / 'data.txt'
path.write_text('temporary data')
print(path.read_text())
# directory gone automatically here
چرا جذابه؟
خودش فایلهای به درد نخور رو پاک میکنه. دیگه لازم نیست یادت باشه این کار رو دستی انجام بدی.
6. زمانبندی ساده - sched
همه سریع میرن سراغ cron یا APScheduler، ولی پایتون یه سیستم ساده برای خودش داره.
import sched, time
s = sched.scheduler(time.time, time.sleep)
def job(name):
print(f"Running {name} at {time.ctime()}")
s.enter(5, 1, job, argument=('task1',))
s.enter(10, 1, job, argument=('task2',))
s.run()
چرا جذابه؟
برای کارهای کوچک، بدون هیچ سرویس خارجی، عالیه.
7. خاتمهی تمیز اسکریپت با signal
و atexit
اسکریپت ۲۴/۷ داری؟ میخوای مطمئن بشی حتی با Ctrl+C هم تمیز و مرتب به اتمام میرسه؟
import signal, atexit
def cleanup():
print("Cleaning up before exit…")
atexit.register(cleanup)
signal.signal(signal.SIGTERM, lambda s,f: exit(0))
signal.signal(signal.SIGINT, lambda s,f: exit(0))
print("Running forever. Press Ctrl+C.")
while True:
time.sleep(1)
چرا جذابه؟
حتی وقتی وسط کار قطع بشه، مطمئن میشی فایلهای موقت یا کانکشنها درست بسته بشن.
8. آبجکت سبک و بهینه - dataclasses
و slots=True
وقتی هزاران رکورد کوچیک داری، کلاسهای معمولی سنگین میشن. dataclasses
با slots
خیلی سبکتر عمل میکنه.
from dataclasses import dataclass
@dataclass(slots=True)
class Job:
id: int
name: str
status: str = 'pending'
jobs = [Job(i, f'task-{i}') for i in range(10_000)]
print(jobs[0])
چرا جذابه؟
کمتر رم مصرف میکنه و کدت هم تمیزتره.
9. پکیج کردن فایلهای جانبی - importlib.resources
اسکریپت های اتومیشن مهمولا همراه با کد SQL یا متن ایمیل میان. بهجای هاردکد کردن مسیر فایل ها، همهچیز رو داخل یک پکیج بذار و باهم استفاده کن.
import importlib.resources as res
with res.files('my_package').joinpath('templates/email.txt').open() as f:
template = f.read()
print(template)
چرا جذابه؟
اسکریپتت خودکفا میشه. دیگه مشکل «روی سیستم من کار میکنه» نداری.
جمعبندی
همین چند تا قابلیت کوچیک میتونن تفاوت بزرگی بسازن. اسکریپتهایی که قبلاً شلوغ و سخت بودن، الان تمیز، سبک و قابل نگهداری میشن. دفعه بعدی که خواستی یه کار رو اتومات کنی، یکی از این ترفندها رو امتحان کن 😉