Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Platforma va interpretator
- 2.2. Jarayon ma'lumotlari
- 2.3. Muhit o'zgaruvchilari
- 2.4. Chiqish kodlari
- 2.5. Standart oqimlar
- 2.6. sys.argv, sys.path, sys.modules
- 2.7. Fayl tizimi: os darajasi
- 2.8. Platforma farqlari
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Platforma, interpretator va jarayon
- Misol 2 — Muhit o'zgaruvchilari
- Misol 3 — Chiqish kodlari va oqimlar
- Misol 4 — Amaliy: katalog tahlili CLI vositasi
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
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:
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_countvaos.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,stderrva nega xatolarstderrga sys.argvvasys.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
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):
finallybloklari vawithtozalash bajariladiexcept Exceptionuni ushlamaydi (SystemExit—BaseExceptionvorisi)- Kutubxona kodida
sys.exitchaqirmang — 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 |
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.
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:
for katalog, ichki, fayllar in os.walk(ildiz):
ichki[:] = [d for d in ichki if d not in {".git", "node_modules"}] # ⭐ [:] — joyidaAtomar yozish — o'quvchi hech qachon yarim yozilgan faylni ko'rmaydi:
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
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) # atomarQoidalar
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
"""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:
=== 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: TrueNima ko'rsatdi: 2.1, 2.2, 2.6, 2.8-bo'limlar.
Misol 2 — Muhit o'zgaruvchilari
"""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:
=== 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: majburiyNima ko'rsatdi: 2.3-bo'lim.
Misol 3 — Chiqish kodlari va oqimlar
"""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:
=== 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.
"""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:
=== 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'radiNima 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
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
DEBUG = bool(os.getenv("DEBUG")) # ❌
DEBUG = os.getenv("DEBUG", "").lower() in {"1", "true", "yes", "on"} # ✅3. Majburiy sozlama tekshirilmagan
url = os.getenv("BAZA_URL") # ⚠️ None — xato keyinroq, boshqa joyda
url = os.environ["BAZA_URL"] # ✅ yoki boshida aniq xabar bilan to'xtash4. Kutubxonada sys.exit
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
if sys.version >= "3.9": ... # ❌ "3.14" < "3.9"
if sys.version_info >= (3, 9): ... # ✅6. os.walk da kesish ishlamaydi
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
with open("sozlama.json", "w") as f: json.dump(...) # ⚠️ uzilish — buzilgan fayl
# ✅ vaqtinchalik fayl + os.replace8. Maxfiy qiymatlarni jurnalga yozish
logging.info("muhit: %s", dict(os.environ)) # ❌ tokenlar jurnalda7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 2.3-dars (o'tilgan):
PATHva 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—stderrga diagnostika - 19.6-dars: CLI dasturni paket sifatida chiqarish
- 26-qism: avtomatlashtirish,
cron, CI
8. Eng yaxshi amaliyotlar
Chiqish kodlari: 0 — muvaffaqiyat, 1 — xato, 2 — noto'g'ri foydalanish.
Natija —
stdout, diagnostika —stderr.Sozlamalarni boshida bir marta o'qing, turga o'giring va tekshiring.
Mantiqiy qiymatlarni aniq ro'yxat bilan tahlil qiling.
Kutubxona — istisno, kirish nuqtasi —
sys.exit(main()).Platformaga bog'liq kodni
sys.platformbilan ajrating va ikkala platformada sinang.Muhim fayllarni atomar yozing —
os.replace.Maxfiy muhit qiymatlarini hech qachon chop etmang.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
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
TruexTrueFalse— satrlar belgima-belgi:'9' > '1'FalseTruebyeTruestr.gzTypeErrorTrue
Vazifa 2: Xatolarni tuzating
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
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:
KALIT=qiymatqatorlari,#izohlar, bo'sh qatorlar- Qo'shtirnoqli qiymatlar (
"...",'...') va ichidagi= ${BOSHQA}havolalarini almashtirishustiga_yoz=Falsebo'lsa mavjudos.environqiymatlari saqlansin- Xato qatorlarni qator raqami bilan
stderrga yozing
Vazifa 4: Tizim haqida hisobot
tizim_hisoboti.py — --json bayrog'i bilan yoki odam o'qiydigan jadval:
- Python versiyasi, interpretator, platforma, 64 bitmi
- Yadrolar (
cpu_countvaprocess_cpu_count) PATHdagi kataloglar va ulardan qaysilari mavjud emas- Maxfiy ko'rinadigan muhit kalitlari (
TOKEN,SECRET,PASSWORD,KEY) — faqat nomlari - Chiqish kodi: muammo topilsa 1
Vazifa 5: tree vositasi
os.scandirbilan rekursiv daraxt chizing (├──,└──)--chuqurlik=N,--yashirin(nuqtali fayllar) bayroqlari- Katalog hajmlari va fayllar soni
- Ruxsat yo'q kataloglarda yiqilmasin —
stderrga ogohlantirish os.walkversiyasi bilan tezlikni solishtiring
Vazifa 6: Ishonchli skript qobig'i
ishonchli_ishga_tushir(funksiya) dekoratorini yozing:
- Istisnoni ushlab,
stderrga qisqa xabar va kod 1 KeyboardInterrupt— kod 130, "to'xtatildi" xabariBrokenPipeError(| headbilan) — jim chiqish- Maxsus
FoydalanuvchiXatosi— kod 2 - Har holat uchun
subprocessbilan 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
- Oddiy sozlamalar (port, rejim, URL) — muhit o'zgaruvchilari
- Maxfiy qiymatlar — imkon bo'lsa fayl yoki boshqaruvchi; muhitda bo'lsa ham:
- dastur boshida o'qib, keraksiz bo'lsa
os.environdan o'chiring - bola jarayonlarga
env=bilan faqat keraklisini bering - jurnallar va xato hisobotlarida yashiring
- dastur boshida o'qib, keraksiz bo'lsa
.envfayllarni hech qachon commit qilmang- Tokenlarni muntazam almashtiring va minimal ruxsat bering
5. Xulosa
- Muhit o'zgaruvchilari — sozlama uchun universal va qulay kanal
- Maxfiy qiymatlar uchun u yetarlicha himoyalanmagan
- Qatlamli yondashuv: oddiy sozlama — muhit, maxfiy — fayl/boshqaruvchi, iloji bo'lsa — qisqa muddatli ma'lumotlar
- 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:
Chiqish kodi va oqimlar — dasturning tizim bilan "shartnomasi". 0 — muvaffaqiyat, 1 — xato, 2 — noto'g'ri foydalanish;
sys.exit("matn")1 qaytaradi va xabarnistderrga yozadi. Natijastdoutga, diagnostikastderrga — shunda quvurlar va fayllar buzilmaydi,cronva CI esa xatoni ko'radi.sys.exit—SystemExitistisnosi:finallybajariladi,except Exceptionuni ushlamaydi, kutubxonalarda esa uning o'rniga istisno ko'tariladi.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;subprocessgaenv={**os.environ, ...}beriladi. Windows'da kalitlar harfga farqsiz, maxfiy qiymatlar esa hech qachon chop etilmaydi.Platforma va fayl tizimi. Versiya —
sys.version_infokortej bilan, platforma —sys.platformbilan tekshiriladi.os.walkda kesishichki[:] = ...bilan, muhim fayllar vaqtinchalik fayl vaos.replacebilan atomar yoziladi (os.renameWindows'da mavjud faylga yozmaydi). Konteynerda yadrolar soninios.process_cpu_count()beradi.
Keyingi darsda fayl yo'llari bilan ishlashning zamonaviy usuliga o'tamiz: pathlib — yo'llarni satr emas, obyekt sifatida boshqarish.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!