IlmHamroh
Python kursi/Standart kutubxona11/16-dars26 daqiqa
Mundarija (22)

15.11-dars: os va sys

15-QISM — STANDART KUTUBXONA · 11-dars


1. Kirish va motivatsiya

Har bir Python dasturi bo'shliqda ishlamaydi: u operatsion tizim ichida, jarayon sifatida, qandaydir muhit o'zgaruvchilari, buyruq qatori argumentlari va standart oqimlar bilan ishga tushadi. Tugaganda esa tizimga chiqish kodi qaytaradi.

Ikki modul shu chegarani boshqaradi:

Modul Nima haqida
sys Python interpretatori: versiya, argumentlar, oqimlar, modul yo'llari, chiqish
os Operatsion tizim: muhit, jarayon, fayl tizimi, platforma farqlari

Real vaziyat. Jamoa ma'lumotlarni zaxiralash skriptini yozdi va uni har tunda cron orqali ishga tushirdi. Skript xato bo'lganda shunday qilardi:

python
except Exception as xato:
    print(f"XATO: {xato}")

Uch oy davomida zaxira bironta ham yaratilmadi — va hech kim bilmadi. Sabab: xato xabari stdout ga yozilgan, skript esa 0 kodi bilan tugagan. cron va monitoring tizimi uchun 0 — "muvaffaqiyat". To'g'ri variant — sys.stderr ga yozish va sys.exit(1).

Boshqa jamoa sozlamani DEBUG = bool(os.getenv("DEBUG")) bilan o'qidi. Ishlab chiqarishda DEBUG=false qo'yildi — va sayt xato sahifalarida maxfiy ma'lumotlarni ko'rsata boshladi: bool("false") — True.

Bu darsda dastur va tizim orasidagi chegarani to'g'ri boshqarishni o'rganamiz. Fayl yo'llari bilan ishlash — keyingi darsda (pathlib).

Bu darsda:

  • Platforma va interpretator ma'lumotlari: sys.platform, sys.version_info, os.name
  • Jarayon: os.getpid, os.cpu_count va os.process_cpu_count (3.13)
  • Muhit o'zgaruvchilari: os.environ, os.getenv, bola jarayonlar, turga o'girish tuzoqlari
  • Chiqish kodlari: sys.exit, SystemExit, 0/1/2 kelishuvi
  • Standart oqimlar: stdin, stdout, stderr va nega xatolar stderr ga
  • sys.argv va sys.path, sys.modules
  • Fayl tizimi: os.walk, os.scandir, os.makedirs, os.replace — atomar almashtirish
  • Platforma farqlari: ajratgichlar, katta-kichik harf, rename
  • Amaliy: katalog tahlili CLI vositasi

2. Nazariya — chuqur tushuntirish

2.1. Platforma va interpretator

Qiymat Misol Qachon ishlatish
sys.platform "win32", "linux", "darwin" Platformaga bog'liq kod
os.name "nt", "posix" Faqat Windows / Unix-ga o'xshash
sys.version_info (3, 14, 5, 'final', 0) Versiya tekshiruvi: >= (3, 12)
sys.implementation.name "cpython", "pypy" Interpretator turi
sys.executable Python fayli yo'li Bola jarayonni shu Python bilan ishga tushirish
sys.maxsize 2**63 - 1 64 bitli ekanini aniqlash
sys.byteorder "little" Binar formatlar

Versiyani satr sifatida solishtirmang: "3.9" > "3.14" — True. Doim sys.version_info >= (3, 14).

Linux'ni sys.platform == "linux" bilan tekshiring — startswith("linux") eski Python uchun edi.

2.2. Jarayon ma'lumotlari

Funksiya Qaytaradi
os.getpid() Joriy jarayon raqami
os.getppid() Ota jarayon raqami
os.cpu_count() Tizimdagi mantiqiy yadrolar
os.process_cpu_count() 3.13+: shu jarayonga ruxsat berilgan yadrolar (konteyner, taskset)
os.getcwd() / os.chdir() Joriy katalog
os.urandom(n) Kriptografik tasodifiy baytlar

Konteynerda os.cpu_count() butun serverning yadrolarini qaytarishi mumkin — pul hajmini hisoblashda process_cpu_count() (14.5-dars).

os.chdir butun jarayon uchun o'zgaradi — iplar va kutubxonalarga ta'sir qiladi. Yo'llarni to'liq ko'rsatish afzal.

2.3. Muhit o'zgaruvchilari

python
os.environ["KALIT"]              # yo'q bo'lsa KeyError
os.environ.get("KALIT", "sukut") # ⭐
os.getenv("KALIT", "sukut")      # xuddi shu
os.environ["KALIT"] = "qiymat"   # faqat str
Fakt Tafsilot
Qiymatlar Faqat str — int berilsa TypeError
Katta-kichik harf Windows'da farqsiz, Linux/macOS'da farqli
Bola jarayonlar O'zgartirilgan os.environ ni meros qilib oladi
Ota jarayon Bola o'zgarishlari qaytmaydi
subprocess.run(env=...) To'liq almashtiradi — {**os.environ, "X": "1"}

Turga o'girish tuzoqlari:

Kod KALIT="false" KALIT="0" Kalit yo'q
bool(os.getenv("KALIT")) True True False
os.getenv("KALIT") == "1" False False False
Aniq ro'yxat bilan tahlil False False Sukut
int(os.getenv("PORT")) — — TypeError: int() argument must be ... not 'NoneType'

Qoida: sozlamalarni dastur boshida bir marta o'qing, turga o'giring, tekshiring va aniq xato bilan to'xtating (13.8-dars: pydantic-settings).

Maxfiy qiymatlarni (*_TOKEN, *_PASSWORD) jurnalga yozmang — muhitni chop etayotganda yashiring.

2.4. Chiqish kodlari

sys.exit(...) Chiqish kodi stderr
sys.exit() / sys.exit(None) / oxirigacha bajarildi 0 —
sys.exit(0) 0 —
sys.exit(3) 3 —
sys.exit("xabar") 1 xabar
Ushlanmagan istisno 1 Traceback

Kelishuvlar (Unix):

Kod Ma'nosi
0 Muvaffaqiyat
1 Umumiy xato
2 Noto'g'ri foydalanish (argumentlar) — argparse ham shuni qaytaradi
130 Ctrl+C bilan to'xtatilgan (128 + SIGINT)

sys.exit — bu raise SystemExit(kod):

  • finally bloklari va with tozalash bajariladi
  • except Exception uni ushlamaydi (SystemExit — BaseException vorisi)
  • Kutubxona kodida sys.exit chaqirmang — istisno ko'taring, chiqishni dastur kirish nuqtasi hal qilsin

os._exit(kod) — darhol chiqish, finally va buferlarsiz; faqat fork qilingan bola jarayonda.

2.5. Standart oqimlar

Oqim Maqsadi
sys.stdin Kiritish (pipe, fayl, klaviatura)
sys.stdout Natija — keyingi dasturga uzatiladi
sys.stderr Diagnostika: xatolar, ogohlantirishlar, jarayon holati
bash
python tahlil.py > natija.json 2> xatolar.log
python tahlil.py | jq .

Agar xabar stdout ga yozilsa, u natija.json ni buzadi va keyingi dastur uni ma'lumot deb o'qiydi.

python
print("natija", file=sys.stdout)
print("ogohlantirish: ...", file=sys.stderr)

sys.stdout.reconfigure(encoding="utf-8") — oqim kodlashini o'zgartirish (Windows eski konsollari).

2.6. sys.argv, sys.path, sys.modules

Qiymat Tafsilot
sys.argv[0] Skript nomi (-c bilan — "-c")
sys.argv[1:] Argumentlar — qobiq allaqachon bo'lgan, qo'shtirnoqlar olib tashlangan
sys.orig_argv Interpretatorga berilgan to'liq buyruq (3.10+)
sys.path Modul qidiriladigan kataloglar ro'yxati
sys.modules Yuklangan modullar keshi (import avval shu yerga qaraydi)

Argumentlarni qo'lda tahlil qilish faqat eng oddiy holatlarda; aks holda — argparse (15.15-dars).

sys.path.append(...) bilan importni "tuzatish" — vaqtinchalik yechim; to'g'risi — paket tuzilishi va o'rnatish (19-qism).

2.7. Fayl tizimi: os darajasi

Funksiya Nima qiladi
os.listdir(yol) Nomlar ro'yxati
os.scandir(yol) DirEntry iteratori — is_dir(), stat() qo'shimcha tizim chaqiruvisiz
os.walk(yol) Rekursiv: (katalog, ichki_kataloglar, fayllar)
os.makedirs(yol, exist_ok=True) Oraliq kataloglar bilan yaratish
os.remove, os.rmdir Fayl / bo'sh katalogni o'chirish
os.rename(a, b) Windows'da b mavjud bo'lsa FileExistsError
os.replace(a, b) Hamma platformada ustiga yozadi, bir fayl tizimida atomar
os.stat(yol) Hajm, vaqtlar, ruxsatlar

os.walk da kesish: ichki_kataloglar ro'yxatini joyida o'zgartirish walk ni o'sha kataloglarga kirmaydigan qiladi:

python
for katalog, ichki, fayllar in os.walk(ildiz):
    ichki[:] = [d for d in ichki if d not in {".git", "node_modules"}]   # ⭐ [:] — joyida

Atomar yozish — o'quvchi hech qachon yarim yozilgan faylni ko'rmaydi:

python
vaqtinchalik = yol + ".tmp"
with open(vaqtinchalik, "w") as f:
    f.write(matn)
    f.flush(); os.fsync(f.fileno())
os.replace(vaqtinchalik, yol)

Yo'llarni birlashtirish va tahlil qilish uchun zamonaviy vosita — pathlib (15.12-dars).

2.8. Platforma farqlari

Windows Linux / macOS
os.sep \ /
os.pathsep (PATH ajratgichi) ; :
os.linesep \r\n \n
Muhit kalitlari Harfga farqsiz Harfga farqli
Fayl nomlari Odatda harfga farqsiz Linux — farqli, macOS — odatda farqsiz
os.rename mavjud faylga FileExistsError Ustiga yozadi
Ochiq faylni o'chirish PermissionError Mumkin
Asinxron loop ProactorEventLoop SelectorEventLoop

Matn faylga yozishda os.linesep ni qo'lda ishlatmang — matn rejimidagi open \n ni o'zi o'giradi (16.1-dars).


3. Tez ma'lumotnoma

python
import os
import sys

if sys.version_info < (3, 12):
    sys.exit("Python 3.12+ kerak")
if sys.platform == "win32": ...

port = int(os.environ.get("PORT", "8000"))
debug = os.environ.get("DEBUG", "").lower() in {"1", "true", "yes", "on"}

print(natija)                                 # stdout — ma'lumot
print("ogohlantirish", file=sys.stderr)       # stderr — diagnostika
sys.exit(0)                                   # 0 muvaffaqiyat, 1 xato, 2 foydalanish

for katalog, ichki, fayllar in os.walk(ildiz):
    ichki[:] = [d for d in ichki if not d.startswith(".")]
os.replace(vaqtinchalik, yakuniy)             # atomar

Qoidalar

versiya — sys.version_info kortej bilan
muhit — get + aniq turga o'girish; bool("false") == True
xato — stderr + nol bo'lmagan chiqish kodi
kutubxonada sys.exit emas — istisno
os.walk kesish — ichki[:] = ...
ustiga yozish — os.replace, rename emas
konteynerda yadrolar — os.process_cpu_count()

4. Batafsil misollar

Misol 1 — Platforma, interpretator va jarayon

python
"""sys.platform, os.name, versiya tekshiruvi; ajratgichlar; sys.executable; yadrolar soni; sys.path va sys.modules; getcwd va chdir ta'siri."""

import os
import sys
import tempfile


def main() -> None:
    print("=== 1. Platforma ===")
    print(f"  sys.platform = {sys.platform!r}, os.name = {os.name!r}")
    print(f"  Windows: {sys.platform == 'win32'}, Linux: {sys.platform == 'linux'}, macOS: {sys.platform == 'darwin'}")
    print(f"  ajratgichlar: sep={os.sep!r}, pathsep={os.pathsep!r}, linesep={os.linesep!r}")
    print("  ⭐ natija Windows'da olingan; Linux'da: 'linux', 'posix', '/', ':', '\\n'")

    print("\n=== 2. ⚠️ Versiya tekshiruvi ===")
    print(f"  version_info[:2] = {sys.version_info[:2]}, >= (3, 12): {sys.version_info >= (3, 12)}")
    print(f"  ⚠️ satr sifatida: '3.9' > '3.14' → {'3.9' > '3.14'}")
    print(f"  kortej sifatida: (3, 9) > (3, 14) → {(3, 9) > (3, 14)}")
    print(f"  interpretator: {sys.implementation.name}, 64 bit: {sys.maxsize == 2**63 - 1}, bayt tartibi: {sys.byteorder}")
    print(f"  sys.executable mavjud fayl: {os.path.isfile(sys.executable)}")

    print("\n=== 3. Jarayon ===")
    print(f"  pid musbat: {os.getpid() > 0}, ota pid boshqa: {os.getppid() != os.getpid()}")
    print(f"  cpu_count >= 1: {os.cpu_count() >= 1}")
    print(f"  process_cpu_count <= cpu_count: {os.process_cpu_count() <= os.cpu_count()}  (3.13+)")
    print(f"  os.urandom(16) uzunligi: {len(os.urandom(16))}, ikki chaqiruv bir xil emas: {os.urandom(16) != os.urandom(16)}")

    print("\n=== 4. sys.path va sys.modules ===")
    print(f"  sys.path — ro'yxat: {isinstance(sys.path, list)}, site-packages bor: {any('site-packages' in p for p in sys.path)}")
    print(f"  'csv' yuklanganmi: {'csv' in sys.modules}")
    import csv  # noqa: F401
    print(f"  import dan keyin: {'csv' in sys.modules}")
    print(f"  qayta import keshdan: {sys.modules['csv'] is csv}")

    print("\n=== 5. ⚠️ chdir butun jarayonga ta'sir qiladi ===")
    asl = os.getcwd()
    with tempfile.TemporaryDirectory() as vaqtinchalik:
        os.chdir(vaqtinchalik)
        with open("nisbiy.txt", "w", encoding="utf-8") as f:
            f.write("salom")
        print(f"  nisbiy fayl yangi katalogga yozildi: {os.path.isfile(os.path.join(vaqtinchalik, 'nisbiy.txt'))}")
        print(f"  asl katalogda yo'q: {not os.path.isfile(os.path.join(asl, 'nisbiy.txt'))}")
        os.chdir(asl)
    print(f"  qaytarildi: {os.getcwd() == asl}")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Platforma ===
  sys.platform = 'win32', os.name = 'nt'
  Windows: True, Linux: False, macOS: False
  ajratgichlar: sep='\\', pathsep=';', linesep='\r\n'
  ⭐ natija Windows'da olingan; Linux'da: 'linux', 'posix', '/', ':', '\n'

=== 2. ⚠️ Versiya tekshiruvi ===
  version_info[:2] = (3, 14), >= (3, 12): True
  ⚠️ satr sifatida: '3.9' > '3.14' → True
  kortej sifatida: (3, 9) > (3, 14) → False
  interpretator: cpython, 64 bit: True, bayt tartibi: little
  sys.executable mavjud fayl: True

=== 3. Jarayon ===
  pid musbat: True, ota pid boshqa: True
  cpu_count >= 1: True
  process_cpu_count <= cpu_count: True  (3.13+)
  os.urandom(16) uzunligi: 16, ikki chaqiruv bir xil emas: True

=== 4. sys.path va sys.modules ===
  sys.path — ro'yxat: True, site-packages bor: True
  'csv' yuklanganmi: False
  import dan keyin: True
  qayta import keshdan: True

=== 5. ⚠️ chdir butun jarayonga ta'sir qiladi ===
  nisbiy fayl yangi katalogga yozildi: True
  asl katalogda yo'q: True
  qaytarildi: True

Nima ko'rsatdi: 2.1, 2.2, 2.6, 2.8-bo'limlar.

Misol 2 — Muhit o'zgaruvchilari

python
"""environ va getenv; faqat satrlar; harfga sezgirlik; bola jarayon merosi va env=; bool("false") tuzog'i; sozlamalarni bir marta tekshirish; maxfiy qiymatlarni yashirish."""

import os
import subprocess
import sys
from dataclasses import dataclass

ROST = {"1", "true", "yes", "on", "ha"}
YOLGON = {"0", "false", "no", "off", "yo'q", ""}


def bool_oqi(qiymat: str | None, sukut: bool) -> bool:
    if qiymat is None:
        return sukut
    toza = qiymat.strip().lower()
    if toza in ROST:
        return True
    if toza in YOLGON:
        return False
    raise ValueError(f"mantiqiy qiymat kutilgan, {qiymat!r} keldi")


@dataclass(frozen=True)
class Sozlamalar:
    port: int
    debug: bool
    baza_url: str
    token: str

    @classmethod
    def muhitdan(cls, muhit: dict[str, str]) -> "Sozlamalar":
        xatolar = []
        try:
            port = int(muhit.get("PORT", "8000"))
            if not 1 <= port <= 65535:
                raise ValueError
        except ValueError:
            xatolar.append(f"PORT: 1..65535 oralig'idagi son kerak, {muhit.get('PORT')!r} keldi")
            port = 0
        try:
            debug = bool_oqi(muhit.get("DEBUG"), sukut=False)
        except ValueError as xato:
            xatolar.append(f"DEBUG: {xato}")
            debug = False
        for majburiy in ("BAZA_URL", "TOKEN"):
            if not muhit.get(majburiy):
                xatolar.append(f"{majburiy}: majburiy")
        if xatolar:
            raise ValueError("; ".join(xatolar))
        return cls(port, debug, muhit["BAZA_URL"], muhit["TOKEN"])

    def xavfsiz_korinish(self) -> dict[str, object]:
        return {"port": self.port, "debug": self.debug, "baza_url": self.baza_url, "token": self.token[:4] + "***"}


def main() -> None:
    print("=== 1. environ va getenv ===")
    os.environ["WISAR_REJIM"] = "sinov"
    print(f"  environ['WISAR_REJIM'] = {os.environ['WISAR_REJIM']!r}")
    print(f"  getenv('YOQ', 'sukut') = {os.getenv('YOQ', 'sukut')!r}")
    try:
        os.environ["YOQ_KALIT"]
    except KeyError:
        print("  environ['YOQ_KALIT'] → KeyError")
    try:
        os.environ["PORT_SON"] = 8080  # type: ignore[assignment]
    except TypeError as xato:
        print(f"  environ[...] = 8080 → TypeError: {xato}")

    print("\n=== 2. Harfga sezgirlik (platformaga bog'liq) ===")
    sezgir = os.environ.get("wisar_rejim") is None
    print(f"  kalitlar harfga sezgir: {sezgir}  (Windows'da False, Linux/macOS'da True)")

    print("\n=== 3. Bola jarayonlar ===")
    kod = "import os; print(os.environ.get('WISAR_REJIM'))"
    meros = subprocess.run([sys.executable, "-c", kod], capture_output=True, text=True, check=True)
    almashgan = subprocess.run([sys.executable, "-c", kod], capture_output=True, text=True, check=True,
                               env={**os.environ, "WISAR_REJIM": "bola"})
    subprocess.run([sys.executable, "-c", "import os; os.environ['WISAR_REJIM'] = 'bola_ozgartirdi'"], check=True)
    print(f"  meros: {meros.stdout.strip()!r}")
    print(f"  env={{**os.environ, ...}}: {almashgan.stdout.strip()!r}")
    print(f"  bola o'zgarishi otaga qaytmadi: {os.environ['WISAR_REJIM']!r}")

    print("\n=== 4. ⚠️ bool('false') tuzog'i ===")
    for qiymat in ("false", "0", "", "True", "yes"):
        print(f"  DEBUG={qiymat!r:8} bool() → {bool(qiymat)!s:5}  bool_oqi() → {bool_oqi(qiymat, sukut=False)}")
    try:
        bool_oqi("balki", sukut=False)
    except ValueError as xato:
        print(f"  'balki' → ValueError: {xato}")

    print("\n=== 5. Sozlamalar: bir marta, boshida, aniq xato bilan ===")
    yaxshi = {"PORT": "8080", "DEBUG": "false", "BAZA_URL": "postgresql://localhost/wisar", "TOKEN": "sk_live_abcdef123"}
    s = Sozlamalar.muhitdan(yaxshi)
    print(f"  {s.xavfsiz_korinish()}")
    try:
        Sozlamalar.muhitdan({"PORT": "80a", "DEBUG": "balki"})
    except ValueError as xato:
        for qism in str(xato).split("; "):
            print(f"  ❌ {qism}")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. environ va getenv ===
  environ['WISAR_REJIM'] = 'sinov'
  getenv('YOQ', 'sukut') = 'sukut'
  environ['YOQ_KALIT'] → KeyError
  environ[...] = 8080 → TypeError: str expected, not int

=== 2. Harfga sezgirlik (platformaga bog'liq) ===
  kalitlar harfga sezgir: False  (Windows'da False, Linux/macOS'da True)

=== 3. Bola jarayonlar ===
  meros: 'sinov'
  env={**os.environ, ...}: 'bola'
  bola o'zgarishi otaga qaytmadi: 'sinov'

=== 4. ⚠️ bool('false') tuzog'i ===
  DEBUG='false'  bool() → True   bool_oqi() → False
  DEBUG='0'      bool() → True   bool_oqi() → False
  DEBUG=''       bool() → False  bool_oqi() → False
  DEBUG='True'   bool() → True   bool_oqi() → True
  DEBUG='yes'    bool() → True   bool_oqi() → True
  'balki' → ValueError: mantiqiy qiymat kutilgan, 'balki' keldi

=== 5. Sozlamalar: bir marta, boshida, aniq xato bilan ===
  {'port': 8080, 'debug': False, 'baza_url': 'postgresql://localhost/wisar', 'token': 'sk_l***'}
  ❌ PORT: 1..65535 oralig'idagi son kerak, '80a' keldi
  ❌ DEBUG: mantiqiy qiymat kutilgan, 'balki' keldi
  ❌ BAZA_URL: majburiy
  ❌ TOKEN: majburiy

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Chiqish kodlari va oqimlar

python
"""sys.exit variantlari va chiqish kodlari; SystemExit va finally; except Exception ushlamaydi; stdout va stderr ajratish; kirish nuqtasi andozasi; sys.argv."""

import subprocess
import sys

BOLA = """
import sys
rejim = sys.argv[1]
if rejim == "yakun":       pass
elif rejim == "nol":       sys.exit(0)
elif rejim == "kod":       sys.exit(3)
elif rejim == "matn":      sys.exit("xato: fayl topilmadi")
elif rejim == "istisno":   raise ValueError("kutilmagan")
elif rejim == "oqimlar":
    print('{"natija": 42}')
    print("ogohlantirish: kesh eskirgan", file=sys.stderr)
"""


def ishga_tushir(*argumentlar: str) -> subprocess.CompletedProcess[str]:
    return subprocess.run([sys.executable, "-c", BOLA, *argumentlar], capture_output=True, text=True)


def main() -> None:
    print("=== 1. Chiqish kodlari ===")
    for rejim in ("yakun", "nol", "kod", "matn", "istisno"):
        n = ishga_tushir(rejim)
        stderr = n.stderr.strip().splitlines()[-1] if n.stderr.strip() else ""
        print(f"  {rejim:8} → kod {n.returncode}  stderr: {stderr!r}")

    print("\n=== 2. stdout va stderr ajratilgan ===")
    n = ishga_tushir("oqimlar")
    print(f"  stdout (ma'lumot):     {n.stdout.strip()!r}")
    print(f"  stderr (diagnostika):  {n.stderr.strip()!r}")
    print("  ⭐ `> natija.json` faqat stdout ni oladi — JSON buzilmaydi")

    print("\n=== 3. SystemExit — istisno ===")
    tozalash = []
    try:
        try:
            sys.exit(2)
        finally:
            tozalash.append("finally bajarildi")
    except SystemExit as chiqish:
        print(f"  SystemExit ushlandi, code={chiqish.code}, {tozalash}")
    try:
        try:
            sys.exit(1)
        except Exception:
            print("  bu qator chiqmaydi")
    except SystemExit:
        print(f"  except Exception SystemExit ni ushlamadi: {not issubclass(SystemExit, Exception)}")

    print("\n=== 4. sys.argv ===")
    n = subprocess.run([sys.executable, "-c", "import sys; print(sys.argv)", "fayl nomi.txt", "--chuqurlik=3"],
                       capture_output=True, text=True)
    print(f"  {n.stdout.strip()}")
    print("  ⭐ bo'shliqli argument bitta element — qobiq qo'shtirnoqlarni olib tashlagan")

    print("\n=== 5. Kirish nuqtasi andozasi ===")
    print("  def main(argv: list[str]) -> int:")
    print("      try: ... return 0")
    print("      except FoydalanuvchiXatosi as x: print(x, file=sys.stderr); return 2")
    print("      except Exception: logging.exception(...); return 1")
    print("  if __name__ == '__main__':")
    print("      sys.exit(main(sys.argv[1:]))")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Chiqish kodlari ===
  yakun    → kod 0  stderr: ''
  nol      → kod 0  stderr: ''
  kod      → kod 3  stderr: ''
  matn     → kod 1  stderr: 'xato: fayl topilmadi'
  istisno  → kod 1  stderr: 'ValueError: kutilmagan'

=== 2. stdout va stderr ajratilgan ===
  stdout (ma'lumot):     '{"natija": 42}'
  stderr (diagnostika):  'ogohlantirish: kesh eskirgan'
  ⭐ `> natija.json` faqat stdout ni oladi — JSON buzilmaydi

=== 3. SystemExit — istisno ===
  SystemExit ushlandi, code=2, ['finally bajarildi']
  except Exception SystemExit ni ushlamadi: True

=== 4. sys.argv ===
  ['-c', 'fayl nomi.txt', '--chuqurlik=3']
  ⭐ bo'shliqli argument bitta element — qobiq qo'shtirnoqlarni olib tashlagan

=== 5. Kirish nuqtasi andozasi ===
  def main(argv: list[str]) -> int:
      try: ... return 0
      except FoydalanuvchiXatosi as x: print(x, file=sys.stderr); return 2
      except Exception: logging.exception(...); return 1
  if __name__ == '__main__':
      sys.exit(main(sys.argv[1:]))

Nima ko'rsatdi: 2.4, 2.5, 2.6-bo'limlar.

Misol 4 — Amaliy: katalog tahlili CLI vositasi

Kirishdagi vaziyatni hisobga olgan holda to'liq CLI vositasi yozamiz: katalog_tahlil <yol> [--eng-katta N]. U os.walk bilan katalogni aylanadi (.git, node_modules, __pycache__ ni kesib), kengaytmalar bo'yicha hajmni hisoblaydi, eng katta fayllarni topadi, natijani atomar JSON faylga yozadi va stdout/stderr hamda chiqish kodlarini to'g'ri ishlatadi. Minimal hajm chegarasi muhit o'zgaruvchisidan o'qiladi. Sinov uchun vaqtinchalik katalog yaratiladi va vosita alohida jarayonda ishga tushiriladi — xuddi terminaldan chaqirilgandek.

python
"""os.walk kesish bilan; scandir; hajm statistikasi; atomar JSON yozish os.replace bilan; muhitdan chegara; argv tahlili; stdout/stderr; 0/1/2 chiqish kodlari."""

import json
import os
import subprocess
import sys
import tempfile
import textwrap

VOSITA = textwrap.dedent('''
    import json, os, sys
    from collections import Counter

    OTKAZ = {".git", "node_modules", "__pycache__"}

    def argumentlar(argv):
        if not argv or argv[0] in {"-h", "--help"}:
            raise SystemExit(2)
        yol, eng_katta = argv[0], 3
        for arg in argv[1:]:
            if arg.startswith("--eng-katta="):
                eng_katta = int(arg.split("=", 1)[1])
            else:
                print(f"noma'lum argument: {arg}", file=sys.stderr)
                raise SystemExit(2)
        return yol, eng_katta

    def tahlil(ildiz, minimal):
        hajmlar, fayllar, otkazilgan, xatolar = Counter(), [], 0, 0
        for katalog, ichki, nomlar in os.walk(ildiz, onerror=lambda x: None):
            oldin = len(ichki)
            ichki[:] = sorted(d for d in ichki if d not in OTKAZ)
            otkazilgan += oldin - len(ichki)
            for nom in nomlar:
                try:
                    hajm = os.stat(os.path.join(katalog, nom)).st_size
                except OSError:
                    xatolar += 1
                    continue
                if hajm < minimal:
                    continue
                kengaytma = os.path.splitext(nom)[1].lower() or "(yo'q)"
                hajmlar[kengaytma] += hajm
                fayllar.append((hajm, os.path.relpath(os.path.join(katalog, nom), ildiz).replace(os.sep, "/")))
        return hajmlar, fayllar, otkazilgan, xatolar

    def atomar_yoz(yol, malumot):
        vaqtinchalik = yol + ".tmp"
        with open(vaqtinchalik, "w", encoding="utf-8") as f:
            json.dump(malumot, f, ensure_ascii=False, indent=1)
            f.flush()
            os.fsync(f.fileno())
        os.replace(vaqtinchalik, yol)

    def main(argv):
        try:
            ildiz, eng_katta = argumentlar(argv)
        except (SystemExit, ValueError):
            print("foydalanish: katalog_tahlil <yol> [--eng-katta=N]", file=sys.stderr)
            return 2
        if not os.path.isdir(ildiz):
            print(f"xato: katalog topilmadi: {ildiz}", file=sys.stderr)
            return 1
        minimal = int(os.environ.get("TAHLIL_MIN_BAYT", "0"))
        hajmlar, fayllar, otkazilgan, xatolar = tahlil(ildiz, minimal)
        natija = {
            "jami_bayt": sum(hajmlar.values()),
            "fayllar": len(fayllar),
            "kengaytmalar": dict(hajmlar.most_common()),
            "eng_kattalar": [yol for _, yol in sorted(fayllar, key=lambda x: (-x[0], x[1]))[:eng_katta]],
            "otkazilgan_kataloglar": otkazilgan,
        }
        atomar_yoz(os.path.join(ildiz, "tahlil.json"), natija)
        print(json.dumps(natija, ensure_ascii=False))
        print(f"tahlil tugadi: {len(fayllar)} fayl, {xatolar} xato", file=sys.stderr)
        return 0

    sys.exit(main(sys.argv[1:]))
''')


def daraxt_yarat(ildiz: str) -> None:
    tuzilma = {
        "src/app.py": 1200, "src/utils.py": 800, "src/__pycache__/app.cpython-314.pyc": 5000,
        "docs/qollanma.md": 3000, "docs/rasm.png": 45000, "node_modules/lib/index.js": 90000,
        ".git/objects/ab": 70000, "README": 400, "data/sotuv.csv": 25000,
    }
    for nisbiy, hajm in tuzilma.items():
        yol = os.path.join(ildiz, *nisbiy.split("/"))
        os.makedirs(os.path.dirname(yol), exist_ok=True)
        with open(yol, "wb") as f:
            f.write(b"x" * hajm)


def ishga_tushir(argv: list[str], muhit: dict[str, str] | None = None) -> subprocess.CompletedProcess[str]:
    return subprocess.run([sys.executable, "-c", VOSITA, *argv], capture_output=True, text=True,
                          env={**os.environ, **(muhit or {})})


def main() -> None:
    with tempfile.TemporaryDirectory() as ildiz:
        daraxt_yarat(ildiz)

        print("=== 1. Oddiy ishga tushirish ===")
        n = ishga_tushir([ildiz])
        natija = json.loads(n.stdout)
        print(f"  kod: {n.returncode}, stderr: {n.stderr.strip()!r}")
        print(f"  jami: {natija['jami_bayt']} bayt, {natija['fayllar']} fayl")
        print(f"  kengaytmalar: {natija['kengaytmalar']}")
        print(f"  eng kattalar: {natija['eng_kattalar']}")
        print(f"  kesilgan kataloglar: {natija['otkazilgan_kataloglar']} (.git, node_modules, __pycache__)")

        print("\n=== 2. Muhitdan chegara va argument ===")
        n = ishga_tushir([ildiz, "--eng-katta=2"], {"TAHLIL_MIN_BAYT": "2000"})
        natija = json.loads(n.stdout)
        print(f"  TAHLIL_MIN_BAYT=2000: {natija['fayllar']} fayl, eng kattalar: {natija['eng_kattalar']}")

        print("\n=== 3. Atomar yozilgan fayl ===")
        with open(os.path.join(ildiz, "tahlil.json"), encoding="utf-8") as f:
            diskdagi = json.load(f)
        print(f"  tahlil.json stdout bilan bir xil: {diskdagi == natija}")
        print(f"  .tmp fayl qolmadi: {not os.path.exists(os.path.join(ildiz, 'tahlil.json.tmp'))}")

        print("\n=== 4. Xato holatlari va chiqish kodlari ===")
        for nom, argv in (("argument yo'q", []), ("noma'lum argument", [ildiz, "--tez"]),
                          ("katalog yo'q", [os.path.join(ildiz, "yoq")])):
            n = ishga_tushir(argv)
            oxirgi = n.stderr.strip().splitlines()[-1].split(": ")[0]    # vaqtinchalik yo'lsiz
            print(f"  {nom:18} → kod {n.returncode}, stdout bo'sh: {n.stdout == ''}, stderr: {oxirgi!r}")

        print("\n=== 5. Monitoring nuqtai nazaridan ===")
        print("  ✅ kod 0 — muvaffaqiyat, natija stdout da")
        print("  ✅ kod 2 — noto'g'ri foydalanish, xabar stderr da")
        print("  ✅ kod 1 — ish bajarilmadi, cron/CI buni ko'radi")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Oddiy ishga tushirish ===
  kod: 0, stderr: 'tahlil tugadi: 6 fayl, 0 xato'
  jami: 75400 bayt, 6 fayl
  kengaytmalar: {'.png': 45000, '.csv': 25000, '.md': 3000, '.py': 2000, "(yo'q)": 400}
  eng kattalar: ['docs/rasm.png', 'data/sotuv.csv', 'docs/qollanma.md']
  kesilgan kataloglar: 3 (.git, node_modules, __pycache__)

=== 2. Muhitdan chegara va argument ===
  TAHLIL_MIN_BAYT=2000: 3 fayl, eng kattalar: ['docs/rasm.png', 'data/sotuv.csv']

=== 3. Atomar yozilgan fayl ===
  tahlil.json stdout bilan bir xil: True
  .tmp fayl qolmadi: True

=== 4. Xato holatlari va chiqish kodlari ===
  argument yo'q      → kod 2, stdout bo'sh: True, stderr: 'foydalanish'
  noma'lum argument  → kod 2, stdout bo'sh: True, stderr: 'foydalanish'
  katalog yo'q       → kod 1, stdout bo'sh: True, stderr: 'xato'

=== 5. Monitoring nuqtai nazaridan ===
  ✅ kod 0 — muvaffaqiyat, natija stdout da
  ✅ kod 2 — noto'g'ri foydalanish, xabar stderr da
  ✅ kod 1 — ish bajarilmadi, cron/CI buni ko'radi

Nima ko'rsatdi: 2.3, 2.4, 2.5, 2.7-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"bool(os.getenv('DEBUG')) — DEBUG=false da False" True — bo'sh bo'lmagan satr
"Muhit kalitlari hamma joyda harfga farqli" Windows'da farqsiz
"Bola jarayon o'zgartirgan muhit otaga o'tadi" Yo'q — faqat pastga meros
"Xatoni chop etsam yetarli" stderr va nol bo'lmagan chiqish kodi kerak
"except Exception sys.exit ni ushlaydi" SystemExit — BaseException
"sys.exit finally ni o'tkazib yuboradi" Bajaradi; os._exit o'tkazadi
"os.rename ustiga yozadi" Windows'da FileExistsError — os.replace
"os.cpu_count() — menga ajratilgan yadrolar" Tizimdagi hammasi; process_cpu_count()

6. Keng tarqalgan xatolar va yechimlari

1. Xato va muvaffaqiyat kodi

python
except Exception as x:
    print("XATO", x)                          # ❌ stdout, kod 0
except Exception as x:
    print("XATO", x, file=sys.stderr)
    sys.exit(1)                               # ✅

2. Mantiqiy muhit o'zgaruvchisi

python
DEBUG = bool(os.getenv("DEBUG"))              # ❌
DEBUG = os.getenv("DEBUG", "").lower() in {"1", "true", "yes", "on"}   # ✅

3. Majburiy sozlama tekshirilmagan

python
url = os.getenv("BAZA_URL")                   # ⚠️ None — xato keyinroq, boshqa joyda
url = os.environ["BAZA_URL"]                  # ✅ yoki boshida aniq xabar bilan to'xtash

4. Kutubxonada sys.exit

python
def ulan(url):
    if not url: sys.exit("url yo'q")          # ❌ chaqiruvchi dasturni o'ldiradi
    if not url: raise ValueError("url yo'q")  # ✅

5. Versiyani satr bilan solishtirish

python
if sys.version >= "3.9": ...                  # ❌ "3.14" < "3.9"
if sys.version_info >= (3, 9): ...            # ✅

6. os.walk da kesish ishlamaydi

python
ichki = [d for d in ichki if d != ".git"]     # ❌ yangi ro'yxat — walk bilmaydi
ichki[:] = [d for d in ichki if d != ".git"]  # ✅

7. Yarim yozilgan fayl

python
with open("sozlama.json", "w") as f: json.dump(...)   # ⚠️ uzilish — buzilgan fayl
# ✅ vaqtinchalik fayl + os.replace

8. Maxfiy qiymatlarni jurnalga yozish

python
logging.info("muhit: %s", dict(os.environ))   # ❌ tokenlar jurnalda

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 2.3-dars (o'tilgan): PATH va muhit
  • 9-qism (o'tilgan): istisnolar ierarxiyasi, BaseException
  • 13.8-dars (o'tilgan): sozlamalarni tekshirish
  • 14.4–14.5-darslar (o'tilgan): jarayonlar va yadrolar soni
  • 15.12–15.14-darslar: pathlib, shutil, subprocess
  • 15.15-dars: argparse — to'liq CLI
  • 15.16-dars: logging — stderr ga diagnostika
  • 19.6-dars: CLI dasturni paket sifatida chiqarish
  • 26-qism: avtomatlashtirish, cron, CI

8. Eng yaxshi amaliyotlar

  1. Chiqish kodlari: 0 — muvaffaqiyat, 1 — xato, 2 — noto'g'ri foydalanish.

  2. Natija — stdout, diagnostika — stderr.

  3. Sozlamalarni boshida bir marta o'qing, turga o'giring va tekshiring.

  4. Mantiqiy qiymatlarni aniq ro'yxat bilan tahlil qiling.

  5. Kutubxona — istisno, kirish nuqtasi — sys.exit(main()).

  6. Platformaga bog'liq kodni sys.platform bilan ajrating va ikkala platformada sinang.

  7. Muhim fayllarni atomar yozing — os.replace.

  8. Maxfiy muhit qiymatlarini hech qachon chop etmang.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
import os, sys
1.  print(bool("false"))
2.  print(os.getenv("BUNDAY_KALIT_YOQ", "x"))
3.  print((3, 9) < (3, 14))
4.  print("3.9" < "3.14")
5.  print(issubclass(SystemExit, Exception))
6.  print(issubclass(SystemExit, BaseException))
7.  try:
        sys.exit("bye")
    except SystemExit as e:
        print(e.code)
8.  print(isinstance(sys.argv, list))
9.  print(type(os.environ.get("PATH")).__name__)
10. print(os.path.splitext("arxiv.tar.gz")[1])
11. try:
        os.environ["N"] = 1
    except TypeError:
        print("TypeError")
12. print(os.process_cpu_count() <= os.cpu_count())
Javoblar
  1. True
  2. x
  3. True
  4. False — satrlar belgima-belgi: '9' > '1'
  5. False
  6. True
  7. bye
  8. True
  9. str
  10. .gz
  11. TypeError
  12. True

Vazifa 2: Xatolarni tuzating

python
1.  def zaxira():
        try:
            nusxa_ol()
        except Exception as xato:
            print("zaxira bajarilmadi:", xato)

2.  PORT = int(os.getenv("PORT"))

3.  def ulanish(url):
        if not url.startswith("postgresql://"):
            sys.exit("noto'g'ri url")

4.  for katalog, ichki, fayllar in os.walk("."):
        ichki = [d for d in ichki if d != "node_modules"]

5.  def sozlama_saqla(yol, malumot):
        with open(yol, "w") as f:
            json.dump(malumot, f)
Javoblar
python
1.  def zaxira() -> int:
        try:
            nusxa_ol()
            return 0
        except Exception as xato:
            print(f"zaxira bajarilmadi: {xato}", file=sys.stderr)
            return 1
    if __name__ == "__main__":
        sys.exit(zaxira())

2.  try:
        PORT = int(os.environ.get("PORT", "8000"))
    except ValueError:
        sys.exit(f"PORT son bo'lishi kerak: {os.environ.get('PORT')!r}")

3.  def ulanish(url):
        if not url.startswith("postgresql://"):
            raise ValueError(f"noto'g'ri url: {url!r}")

4.  for katalog, ichki, fayllar in os.walk("."):
        ichki[:] = [d for d in ichki if d != "node_modules"]

5.  def sozlama_saqla(yol, malumot):
        vaqtinchalik = yol + ".tmp"
        with open(vaqtinchalik, "w", encoding="utf-8") as f:
            json.dump(malumot, f, ensure_ascii=False)
            f.flush()
            os.fsync(f.fileno())
        os.replace(vaqtinchalik, yol)

Vazifa 3: .env fayl o'quvchi

env_yukla(yol, ustiga_yoz=False) funksiyasini yozing:

  1. KALIT=qiymat qatorlari, # izohlar, bo'sh qatorlar
  2. Qo'shtirnoqli qiymatlar ("...", '...') va ichidagi =
  3. ${BOSHQA} havolalarini almashtirish
  4. ustiga_yoz=False bo'lsa mavjud os.environ qiymatlari saqlansin
  5. Xato qatorlarni qator raqami bilan stderr ga yozing

Vazifa 4: Tizim haqida hisobot

tizim_hisoboti.py — --json bayrog'i bilan yoki odam o'qiydigan jadval:

  1. Python versiyasi, interpretator, platforma, 64 bitmi
  2. Yadrolar (cpu_count va process_cpu_count)
  3. PATH dagi kataloglar va ulardan qaysilari mavjud emas
  4. Maxfiy ko'rinadigan muhit kalitlari (TOKEN, SECRET, PASSWORD, KEY) — faqat nomlari
  5. Chiqish kodi: muammo topilsa 1

Vazifa 5: tree vositasi

  1. os.scandir bilan rekursiv daraxt chizing (├──, └──)
  2. --chuqurlik=N, --yashirin (nuqtali fayllar) bayroqlari
  3. Katalog hajmlari va fayllar soni
  4. Ruxsat yo'q kataloglarda yiqilmasin — stderr ga ogohlantirish
  5. os.walk versiyasi bilan tezlikni solishtiring

Vazifa 6: Ishonchli skript qobig'i

ishonchli_ishga_tushir(funksiya) dekoratorini yozing:

  1. Istisnoni ushlab, stderr ga qisqa xabar va kod 1
  2. KeyboardInterrupt — kod 130, "to'xtatildi" xabari
  3. BrokenPipeError (| head bilan) — jim chiqish
  4. Maxsus FoydalanuvchiXatosi — kod 2
  5. Har holat uchun subprocess bilan test

Vazifa 7: O'ylash

"12-faktorli ilova" (The Twelve-Factor App) tamoyillari sozlamalarni muhit o'zgaruvchilarida saqlashni tavsiya qiladi. Boshqa tomondan, muhit o'zgaruvchilari bola jarayonlarga meros bo'ladi, /proc/<pid>/environ orqali ko'rinishi mumkin va xato hisobotlariga tushib qoladi. Nega bu tavsiya shunchalik keng tarqalgan va maxfiy qiymatlar uchun qanday muqobillar bor?

Javob

Qisqa javob: Muhit o'zgaruvchilari — tilga bog'liq bo'lmagan, har qanday platformada mavjud va koddan ajratilgan sozlash mexanizmi: bitta konteyner obrazi turli muhitlarda turli sozlamalar bilan ishlaydi. Oddiy sozlamalar uchun bu ideal. Lekin maxfiy qiymatlar uchun muhit zaif kanal: meros, jarayon ro'yxatlari, xato hisobotlari va jurnallar orqali sizishi mumkin. Shuning uchun maxfiy qiymatlar uchun maxsus boshqaruvchilar, fayllar va qisqa muddatli kalitlar ishlatiladi.

1. Nega muhit o'zgaruvchilari

Afzallik Tafsilot
Kod va sozlama ajratilgan Bitta obraz — dev, test, prod
Tilga bog'liq emas Python, Go, Node — hammasi o'qiydi
Tasodifan commit qilinmaydi Fayl emas (.env dan tashqari)
Orkestratorlar qo'llaydi Docker, Kubernetes, systemd, CI

2. Muhitning xavfli tomonlari

Sizish yo'li Misol
Bola jarayonlar Uchinchi tomon vositasi ham tokenni oladi
Jarayon ma'lumotlari Linux'da /proc/<pid>/environ (bir foydalanuvchi)
Xato hisobotlari Sentry kabi vositalar muhitni to'plashi
Jurnallar logging.info(os.environ)
Diagnostika sahifalari Debug rejimidagi xato sahifalari (kirishdagi vaziyat)
Konteyner tekshiruvi docker inspect muhitni ko'rsatadi

3. Muqobillar

Usul Qanday Afzalligi
Maxfiy fayllar Kubernetes Secret yoki Docker secret — faylga tmpfs da o'rnatiladi Merosga tushmaydi, ruxsatlar bilan himoyalangan
Maxfiy qiymatlar boshqaruvchisi HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager Kirish nazorati, audit, aylantirish (rotation)
Qisqa muddatli ma'lumotlar Bulut IAM rollari, OIDC tokenlar Doimiy kalit umuman yo'q
*_FILE andozasi DB_PASSWORD_FILE=/run/secrets/db Muhitda faqat yo'l
Shifrlangan sozlama SOPS, sealed-secrets Git da saqlash mumkin

4. Amaliy qoidalar

  1. Oddiy sozlamalar (port, rejim, URL) — muhit o'zgaruvchilari
  2. Maxfiy qiymatlar — imkon bo'lsa fayl yoki boshqaruvchi; muhitda bo'lsa ham:
    • dastur boshida o'qib, keraksiz bo'lsa os.environ dan o'chiring
    • bola jarayonlarga env= bilan faqat keraklisini bering
    • jurnallar va xato hisobotlarida yashiring
  3. .env fayllarni hech qachon commit qilmang
  4. Tokenlarni muntazam almashtiring va minimal ruxsat bering

5. Xulosa

  1. Muhit o'zgaruvchilari — sozlama uchun universal va qulay kanal
  2. Maxfiy qiymatlar uchun u yetarlicha himoyalanmagan
  3. Qatlamli yondashuv: oddiy sozlama — muhit, maxfiy — fayl/boshqaruvchi, iloji bo'lsa — qisqa muddatli ma'lumotlar
  4. Qaysi usul bo'lmasin: minimal ruxsat, jurnallarda yashirish, aylantirish

Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.


Xulosa

Bu darsda Python dasturi va operatsion tizim orasidagi chegarani boshqarishni o'rgandik.

Eng muhim uch fikr:

  1. Chiqish kodi va oqimlar — dasturning tizim bilan "shartnomasi". 0 — muvaffaqiyat, 1 — xato, 2 — noto'g'ri foydalanish; sys.exit("matn") 1 qaytaradi va xabarni stderr ga yozadi. Natija stdout ga, diagnostika stderr ga — shunda quvurlar va fayllar buzilmaydi, cron va CI esa xatoni ko'radi. sys.exit — SystemExit istisnosi: finally bajariladi, except Exception uni ushlamaydi, kutubxonalarda esa uning o'rniga istisno ko'tariladi.

  2. Muhit o'zgaruvchilari — faqat satrlar. os.environ.get(...) bilan o'qing, boshida bir marta turga o'giring va tekshiring: bool("false") — True, int(None) — TypeError. O'zgartirilgan muhit bola jarayonlarga meros bo'ladi, lekin otaga qaytmaydi; subprocess ga env={**os.environ, ...} beriladi. Windows'da kalitlar harfga farqsiz, maxfiy qiymatlar esa hech qachon chop etilmaydi.

  3. Platforma va fayl tizimi. Versiya — sys.version_info kortej bilan, platforma — sys.platform bilan tekshiriladi. os.walk da kesish ichki[:] = ... bilan, muhim fayllar vaqtinchalik fayl va os.replace bilan atomar yoziladi (os.rename Windows'da mavjud faylga yozmaydi). Konteynerda yadrolar sonini os.process_cpu_count() beradi.

Keyingi darsda fayl yo'llari bilan ishlashning zamonaviy usuliga o'tamiz: pathlib — yo'llarni satr emas, obyekt sifatida boshqarish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
15.11-dars: os va sys — IlmHamroh