Məzmuna keç
Educora
İrəli20 dəq28 / 42

Avtomatlaşdırma skriptləri

Gündəlik işləri Python-a həvalə et: `pathlib` və `shutil` ilə faylları sırala, `datetime` ilə köhnə faylları tap, `argparse` ilə komanda sətri interfeysi qur, `logging` ilə jurnal yaz və skripti cron və ya Tapşırıq Planlayıcısı ilə plan üzrə işə sal.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • pathlib, os və shutil ilə faylları və qovluqları təhlükəsiz yaratmaq, köçürmək və kopyalamaq
  • datetime və timedelta ilə tarixləri formatlamaq, müqayisə etmək və faylların yaşını hesablamaq
  • argparse və logging ilə peşəkar komanda sətri skripti yazmaq və onu plan üzrə işə salmaq

Leylanın «Yükləmələr» qovluğunda yüzlərlə fayl qarışıq halda durur, hər axşam isə o, sənədlərini əl ilə ehtiyat diskə kopyalayır. Bu, hər gün bir neçə dəqiqə və ara-sıra unudulan ehtiyat nüsxə deməkdir. 25 sətirlik Python skripti faylları saniyələr içində qovluqlara ayırır, sistem planlayıcısı isə onu hər gün özü işə salır. Bu dərsdə belə skriptin bütün hissələrini quracağıq.

Fayllar və qovluqlar: pathlib, os, shutil

TapşırıqKod
qovluğun məzmunu / alt qovluqlarla birlikdəPath.iterdir(), Path.rglob('*.pdf'), os.walk()
qovluq yaratmaqPath.mkdir(parents=True, exist_ok=True)
faylı / qovluğu kopyalamaqshutil.copy2(src, dst), shutil.copytree(src, dst)
köçürmək və ya adını dəyişməkshutil.move(src, dst), Path.rename(new)
faylı / bütün qovluğu silməkPath.unlink(), shutil.rmtree(path)

Aşağıdakı skript faylları uzantısına görə qovluqlara ayırır. Real fayllarına toxunmamaq üçün tempfile.mkdtemp() ilə müvəqqəti qovluq yaradırıq və sonda onu silirik. Diqqət et: .JPG və .jpg eyni sayılır, çünki uzantını lower() ilə kiçik hərflərə çeviririk.

Python
import shutil
import tempfile
from pathlib import Path

root = Path(tempfile.mkdtemp())
for name in ['report.pdf', 'photo1.jpg', 'photo2.JPG', 'notes.txt', 'data.csv', 'song.mp3']:
    (root / name).write_text('demo')

folders = {'.pdf': 'documents', '.txt': 'documents', '.jpg': 'images', '.csv': 'data'}
for file in list(root.iterdir()):
    if file.is_file():
        target = root / folders.get(file.suffix.lower(), 'other')
        target.mkdir(exist_ok=True)
        shutil.move(file, target / file.name)

for path in sorted(root.rglob('*')):
    print(path.relative_to(root).as_posix())
shutil.rmtree(root)
print(root.exists())
▸ Gözlənilən nəticə
data
data/data.csv
documents
documents/notes.txt
documents/report.pdf
images
images/photo1.jpg
images/photo2.JPG
other
other/song.mp3
False
list(root.iterdir()) siyahını əvvəlcədən götürür — qovluğu dövr zamanı dəyişmək təhlükəsiz olsun deyə. Tanınmayan uzantılar other qovluğuna düşür.

Tarix və vaxt

datetime modulunda date, datetime və müddəti ifadə edən timedelta var. strftime tarixi formatlı mətnə çevirir (%Y il, %m ay, %d gün, %H:%M saat), strptime isə əksinə, mətni tarixə. Nəticələr təkrarlana bilsin deyə nümunələrdə datetime.now() əvəzinə sabit tarix götürürük.

Python
from datetime import date, datetime, timedelta

now = datetime(2026, 9, 27, 14, 30)
print(now.strftime('%Y-%m-%d_%H-%M'))
print(now.strftime('%d.%m.%Y'))
deadline = now + timedelta(days=10, hours=3)
print(deadline.isoformat(sep=' '))
print((date(2026, 12, 31) - now.date()).days, 'days left in the year')
parsed = datetime.strptime('05.10.2026 09:15', '%d.%m.%Y %H:%M')
print(parsed, parsed.strftime('%A'))
▸ Gözlənilən nəticə
2026-09-27_14-30
27.09.2026
2026-10-07 17:30:00
95 days left in the year
2026-10-05 09:15:00 Monday

Faylın son dəyişmə vaxtını stat().st_mtime verir (1970-ci ildən bəri saniyələr). Onu datetime.fromtimestamp ilə tarixə çevirib limitlə müqayisə edirik. Nümunədə faylların «yaşını» os.utime ilə süni olaraq təyin edirik:

Python
import os
import tempfile
from datetime import datetime, timedelta
from pathlib import Path

root = Path(tempfile.mkdtemp())
now = datetime(2026, 9, 27, 12, 0)
for name, days in {'backup_old.zip': 45, 'log_week.txt': 7, 'log_today.txt': 0}.items():
    f = root / name
    f.write_text('x')
    t = (now - timedelta(days=days)).timestamp()
    os.utime(f, (t, t))

limit = now - timedelta(days=30)
for f in sorted(root.iterdir()):
    modified = datetime.fromtimestamp(f.stat().st_mtime)
    status = 'OLD' if modified < limit else 'ok'
    print(f'{f.name:15} {modified:%Y-%m-%d} {status}')
▸ Gözlənilən nəticə
backup_old.zip  2026-08-13 OLD
log_today.txt   2026-09-27 ok
log_week.txt    2026-09-20 ok

argparse və logging

Yaxşı skriptin daxilində yollar və rəqəmlər yazılmır — onları komanda sətrindən alır: python cleanup.py downloads --days 14 --dry-run. argparse mövqe arqumentlərini (folder), seçimləri (--days), bayraqları (--dry-run) təhlil edir, tipləri çevirir və --help səhifəsini özü yaradır. Real skriptdə parse_args() arqumentsiz çağırılır; burada komanda sətrini siyahı ilə imitasiya edirik.

Python
import argparse

parser = argparse.ArgumentParser(prog='cleanup', description='List or delete old files.')
parser.add_argument('folder', help='folder to scan')
parser.add_argument('--days', type=int, default=30, help='age limit in days')
parser.add_argument('--dry-run', action='store_true', help='only show what would happen')

args = parser.parse_args(['downloads', '--days', '14', '--dry-run'])
print(args)
print(args.folder, args.days, args.dry_run)
print(parser.parse_args(['photos']))
▸ Gözlənilən nəticə
Namespace(folder='downloads', days=14, dry_run=True)
downloads 14 True
Namespace(folder='photos', days=30, dry_run=False)
--dry-run atributda dry_run olur (defis alt xəttə çevrilir). İkinci çağırışda göstərilməyən seçimlər susmaya görə qiymətlərini alıb.

Plan üzrə işləyən skriptin ekranına heç kim baxmır, ona görə print əvəzinə logging işlədilir: hər mesajın səviyyəsi (DEBUG, INFO, WARNING, ERROR, CRITICAL) və vaxtı olur, onları fayla yazmaq və əhəmiyyətsizləri süzmək olar. %s, %d yer tutucuları mesajı yalnız həqiqətən çap olunanda formatlayır.

Python
import logging
import sys

logging.basicConfig(stream=sys.stdout, level=logging.INFO,
                    format='%(levelname)-8s %(name)s: %(message)s', force=True)
log = logging.getLogger('backup')
log.debug('not shown: the level is INFO')
log.info('Backup started')
log.warning('Disk is 85% full')
try:
    ratio = 10 / 0
except ZeroDivisionError:
    log.error('Could not compute the ratio')
log.info('Copied %d files in %.1f s', 128, 3.42)
▸ Gözlənilən nəticə
INFO     backup: Backup started
WARNING  backup: Disk is 85% full
ERROR    backup: Could not compute the ratio
INFO     backup: Copied 128 files in 3.4 s
Burada jurnal ekrana (sys.stdout) yazılır; real skriptdə filename='backup.log' və formatda %(asctime)s (vaxt) göstərilir. DEBUG səviyyəli mesaj INFO limitindən aşağı olduğu üçün görünmür.

Tam skript və onun planlaşdırılması

Python
import argparse
import logging
import shutil
from datetime import datetime
from pathlib import Path

log = logging.getLogger('backup')

def backup(source, dest_root, dry_run=False):
    stamp = datetime.now().strftime('%Y-%m-%d_%H-%M')
    target = Path(dest_root) / f'{Path(source).name}_{stamp}'
    log.info('Copying %s -> %s (dry run: %s)', source, target, dry_run)
    if not dry_run:
        shutil.copytree(source, target)
    return target

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Back up a folder with a timestamp.')
    parser.add_argument('source', help='folder to copy')
    parser.add_argument('dest', help='where to put the copy')
    parser.add_argument('--dry-run', action='store_true', help='only log, do not copy')
    args = parser.parse_args()
    logging.basicConfig(filename='backup.log', level=logging.INFO,
                        format='%(asctime)s %(levelname)s %(message)s')
    backup(args.source, args.dest, args.dry_run)
backup.py. if __name__ == '__main__': bloku yalnız fayl birbaşa işə salınanda icra olunur — backup funksiyasını başqa skriptlərdə və testlərdə import etmək olar. Öz kompüterində: python backup.py Documents D:/Backup --dry-run, sonra backup.log faylına bax.

Skripti müntəzəm işə salmaq üçün əməliyyat sisteminin planlayıcısından istifadə olunur: Linux və macOS-də cron, Windows-da Tapşırıq Planlayıcısı (Task Scheduler, komanda sətrində schtasks). cron sətrində beş sahə var: dəqiqə, saat, ayın günü, ay, həftənin günü; * «istənilən» deməkdir.

cron ifadəsiNə vaxt
0 21 * * *hər gün saat 21:00-da
*/15 * * * *hər 15 dəqiqədən bir
0 9 * * 1-5iş günləri saat 09:00-da
0 3 1 * *hər ayın 1-i saat 03:00-da
Terminal
# Linux / macOS: open the table with `crontab -e` and add a line
0 21 * * * /home/leyla/.venv/bin/python /home/leyla/scripts/backup.py /home/leyla/Documents /mnt/backup

# Windows (Command Prompt): the same task every day at 21:00
schtasks /Create /SC DAILY /ST 21:00 /TN "Daily backup" /TR "C:\scripts\.venv\Scripts\python.exe C:\scripts\backup.py C:\Users\Leyla\Documents D:\Backup"
Python kitabxanası schedule da var (pip install schedule), amma onunla skript daim açıq qalmalıdır; sistem planlayıcısı kompüter yenidən başlayandan sonra da işləyir.
Tapşırıq

Fayl adlarını uzantıya görə qruplaşdır: uzantını kiçik hərflərlə götür, uzantısı olmayan fayllar üçün '(none)' işlət. Uzantıları sıralanmış halda, hər birinin yanında sıralanmış fayl siyahısı ilə, ayrı sətirlərdə çap et.

Tapşırıq · Python
from pathlib import PurePath

files = ['report.PDF', 'photo.jpg', 'notes.txt', 'scan.pdf', 'song.mp3', 'README']
# group by lowercase extension, then print: extension [sorted names]
▸ Gözlənilən nəticə
(none) ['README']
.jpg ['photo.jpg']
.mp3 ['song.mp3']
.pdf ['report.PDF', 'scan.pdf']
.txt ['notes.txt']
Tapşırıq

Bu gün 2026-09-27-dir. 30 gündən köhnə hər fayl üçün adını və neçə gün əvvəl dəyişdirildiyini çap et (lüğətdəki sıra ilə). Sonda ən yeni faylı newest: <ad> şəklində çap et.

Tapşırıq · Python
from datetime import date

today = date(2026, 9, 27)
files = {'backup.zip': '2026-07-30', 'notes.txt': '2026-09-20',
         'photo.jpg': '2026-08-15', 'log.txt': '2026-09-27'}
# print old files with their age in days, then the newest file
▸ Gözlənilən nəticə
backup.zip 59
photo.jpg 43
newest: log.txt

Əsas fikirlər

  • pathlib yollar və fayllar üçün, shutil kopyalama, köçürmə və qovluqları silmək üçündür; silinən fayllar geri qayıtmır.
  • datetime, timedelta, strftime və strptime; fayl adlarında tarixi YYYY-MM-DD şəklində yaz.
  • argparse mövqe arqumentləri, seçimlər, bayraqlar və avtomatik --help verir.
  • Plan üzrə işləyən skriptlərdə print yox, səviyyələri və vaxtı olan logging işlət.
  • cron və ya Tapşırıq Planlayıcısı skripti müntəzəm işə salır; mütləq yollar, tam python yolu və --dry-run vərdişi.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Hansı funksiya bütün qovluğu içindəkilərlə birlikdə birdəfəlik silir?