Modüller | os

os modülü, işletim sistemiyle alakalı işlemleri yapmamızı sağlayan güzel ve güçlü bir modüldür. Zaten açılımı da "Operating System - İşletim Sistemi" şeklindedir. Bu blog içerisinde birçok komutun açılımını da vereceğim. Böylece aklınızda kalması daha kolay olur. Açılımlara dikkat edelim.

İlk olarak import os diyorum ve modülü projeme ekliyorum.

UNIX sistem kullanıyorsanız ya da Bash Script serisini takip ettiyseniz bilirsiniz ki pwd komutu, o an içerisinde bulunduğunuz konumu gösterir. os modülü ile bu işlem, aşağıdaki gibi yapılır.

os.getcwd()

Gördüğünüz gibi os.getcwd() dedim ve bana şu an bulunduğum lokasyonu verdi. Bu komut, "get current working directory"nin açılımıdır ve anlamı "mevcut çalışma dizinini al" şeklindedir. Peki, isterseniz bulunduğumuz yere bir klasör oluşturalım.

os.mkdir()

'mkdir' komutunun açılımı "make directory" yani "klasör oluştur" şeklindedir. Bunu çalıştırdığım zaman şu anki dizinimin altına denemeKlasoru isminde bir klasör oluşturdu. İsterseniz kontrol edelim.

Bunu bir değişkene atayabilir miyiz? Bunu denemek için ilk önce az önce oluşturduğum klasörü siliyorum ve kodu tekrar çalıştırıyorum.

makeDirectory = os.mkdir("denemeKlasoru") şeklindeki bir kullanım da sorunsuz bir şekilde çalışacaktır. Yani değişken ataması yaparsanız ek olarak herhangi bir işlem yapmanıza gerek kalmadan kodunuz çalışacaktır.

os.mkdir() içerisine sadece bir klasör ismi vermenize gerek yoktur. Ne demek istiyorum?

Gördüğünüz gibi direkt olarak oluşturmak istediğiniz lokasyonu girip bir adet ters slash işareti koyduktan sonra klasörünüzün ismini belirtirseniz Python, o lokasyona kadar gidecek ve o klasörü orada oluşturacaktır.

Peki, C:\Python içerisine oluşturduğumuz denemeKlasoru içine girmek istersek ne yapabiliriz?

os.chdir()

Linux'taki cd <klasör ismi> komutuyla aynı işi yapmaktadır. Açılımı "change directory" yani "klasörü değiştir" şeklindedir.

os.chdir() komutuyla gitmek istediğimiz klasörün adını yazıyoruz. Elbette, bunu da değişkene atadık ve herhangi bir sorunla karşılaşmadık. Tekrar os.getcwd() çalıştırmamın amacı, lokasyon değişikliğinden sonra nerede olduğumuzu bilmekti.

os.chdir() içerisine sadece bir klasör ismi vermenize gerek yoktur. Ne demek istiyorum?

os.mkdir() gibi; lokasyon da verebilirsiniz. Bir klasörün içine girmek için o klasör ile aynı dizinde olmanıza gerek yoktur. Peki, bu ikisini birleştirelim ve C:\Python içerisindeyken C:\BashScript\denemeKlasoru içerisine başka bir klasör daha yaratalım. Şu an C:\BashScript\denemeKlasoru içerisinde herhangi bir klasör veya dosya bulunmuyor.

Şimdi, kodlara dönelim. Burada oldukça sakin olun ve her şeyi adım adım inceleyin. Gerçekleşen adımları anlamanız açısından kodların yanındaki ve en alttaki yeşil yazıları da okumanızı şiddetle öneririm.

Klasörümüzü kontrol edelim:

Kodumuz sorunsuz bir şekilde adım adım çalıştı. Peki, biz her seferinde bunları manyak gibi el ile klasörün içine girip mi kontrol edeceğiz? Elbette hayır.

os.list()

Linux'taki 'ls' komutuyla aynı işi yapar. Klasörün içerisinde ne var ne yoksa bunları listeler.

Gördüğünüz gibi şu an bulunduğumuz konumun içerisinde ne var ne yoksa gösterdi. Ancak dikkat edelim; sade bir şekilde os.listdir() derseniz veya bunu bir değişkene atayarak yaparsanız bir sonuç alamazsınız. Bunu ekrana kendiniz print ettirmelisiniz.

UYARI: Aşağıdaki paragraf bir soru içermektedir. Sorunun cevabını düşünmeden paragrafın altındaki görsele bakmayın.

Ayrıca, şu an oldukça saçma bir çıktı ile karşı karşıyayız. Burada 100 tane dosya olduğunu ve bunların hepsini yan yana yazdığını varsayarsak bunun bir saçmalıktan ibaret olduğunu görebiliriz. Bunun önüne geçmek için siz olsanız ne kullanırdınız?

Doğru cevap for döngüsü idi. Bu sayede hepsini alt alta yazdırabildik.

Bu fonksiyon, yine sadece olduğunuz klasörün içini göstermek zorunda değil. Örneğin C:\Anaconda3 içerisini, C:\Python içerisindeyken görelim.

os.makedirs()

Bunun anlamı da "make directories" yani "klasörler oluştur" şeklindedir. Bu fonksiyon ile iç içe klasörler oluşturabiliyoruz. Örneğin az önce C:\Python altına denemeKlasoru isminde bir klasör oluşturduk. Şimdi, C:\Python\denemeKlasoru\klasor1\klasor2 şeklinde bir dizin yaratmak istiyoruz.

Gördüğünüz gibi makedirs() fonksiyonu ile bunu oluşturduk. İlk önce, olduğunuz klasörün içine gidecek ve klasor1'i oluşturacaktır. Daha sonra ters slash sayesinde bir tane daha oluşturması gerektiğini anlayacak ve klasor1'in içine girip oraya klasor2'yi oluşturacak.

İsterseniz kontrol edelim.

Gördüğünüz gibi bunu çalıştırdım ve hata almadım. Eğer oraya yazdığım klasörü bulamasaydı hata verirdi. Hata vermediğine göre klasörleri bulmuş. Ancak içleri boş olduğu için ekrana herhangi bir çıktı vermedi.

os.remove()

"Remove" kelimesinin anlamı "kaldırmak, unutmak" şeklindedir. Bu fonksiyon, klasörden ziyade normal dosyaları (örneğin .txt) silmenize olanak tanır. Ben, klasor2'nin içine deneme.txt isimli bir dosya oluşturdum ve onu sileceğim.

Yeşil yazıları okuyunuz.

os.rmdir()

Buradaki 'rm', biraz önce gördüğünüz remove kelimesini kasteder. 'dir' ise 'directory' anlamına gelir. Bu fonksiyon ise "içi boş olan klasörleri" silmenize olanak tanır. Şimdi, klasor2'nin içine tekrar deneme.txt isimli bir dosya oluşturacağım ve klasor2'yi, içinde deneme.txt olacak şekilde silmeye çalışacağım.

"OSError: The directory is not empty." şeklinde bir hata aldık. Bize, klasörün boş olmadığını, o yüzden silme işlemini gerçekleştiremediğini söylüyor. Peki, ilk önce klasor2 içerisindeki deneme.txt dosyasını silelim, sonrasında klasor2'yi silelim.

İlk önce os.remove() komutuyla deneme.txt'yi sildik. Sonrasında os.rmdir() komutuyla klasor2'yi sildik. klasor2'nin silinmesi, artık içinin boş olmasından kaynaklanır. Peki, içi dolu olan bir klasörü nasıl sileceğiz?

shutil.rmtree()

Bu konuda ne yazık ki os modülü bizi desteklemiyor. Bunun için shutil modülünden yararlanacağız. shutil modülü şu an konumuz dahilinde değil ama içi dolu olan klasörlerin nasıl silineceği hakkında size bilgi vermem gerektiğini düşündüm.

Dolayısıyla şimdi, klasor1'in içerisinde 2 adet klasör ve 2 adet .txt dosyası koydum.

Şimdi, klasor1'i silmeye çalışacağım. Bunun için ilk önce import shutil dememiz gerekiyor.

import ettikten sonra shutil.rmtree(<lokasyon>) dedim ve klasor1 silindi. Hemen sonrasında Python, for döngüsü ile klasor1'in içerisini görüntülemek istedi ama yapamadı çünkü klasör silindi ve artık ona erişim sağlayamıyor.

Buradaki 'rmtree' mantığından bahsedeyim. 'rm' ifadesi zaten remove anlamına geliyor; biliyorsunuz. Oradaki 'tree' ise 'ağaç' anlamına gelir. Baktığınız zaman klasor1'in kendisi ağacın gövdesi, içerisindeki 4 öğe ise ağacın dalları oluyor. Bunların hepsini silerken tree demelerinin mantığı buradan geliyor. Anlamını bilirseniz aklınızda daha iyi kalır.

Ayrıca os modülü ile yeni bir klasör oluşturabiliyoruz ancak dosya oluşturamıyoruz. Bu konuyu ilerleyen bölümlerde göreceksiniz.

os.rename()

"Rename" kelimesinin anlamı "yeniden adlandır" şeklindedir. Bu fonksiyonu kullanarak bir klasörün ya da dosyanın ismini değiştirebilirsiniz.

Bu arada, normal şartlarda örneğin chdir() kullandığımızda geçici olarak yani arka planda konum değişiyordu. İşte, rename() fonksiyonunda böyle bir şey söz konusu değil; gerçekten isim değişiyor:

os.rename() ile sadece yeniden adlandırma yapmıyoruz. Bir de dosyanın veya klasörün konumunu değiştirebiliyoruz. Bakalım.

İsterseniz bunu, ismi tekrar 'denemeKlasoru' olacak şekilde Python klasörü içine yollayalım.

os.stat()

Buradaki 'stat' kelimesini 'status' yani 'durum' olarak algılayın. Bu fonksiyon, herhangi bir dosya veya klasörün durum bilgisini (en son ne zaman ona erişildi, ne zaman değiştirildi vb.) gösterir. Bakalım.

Gördüğünüz gibi bu bir 'tuple' yani 'demet'. Dolaysıyla bu içeriği değiştiremeyeceğiz. Buradan Python'un Tuple yapılarına da selam yollamış olalım.

Burada dikkatinizi çeken şey yüksek olasılıkla saçma sapan sayılar oldu. Evet, isimlerden belki bir şeyleri tahmin edebiliyoruz ancak sayılardan hiçbir şey anlamıyoruz. Bu konu şimdilik kenarda kalsın, başka bir şey göstereceğim.

Eğer lokasyonu yazdığınız parantezin dışına nokta koyarsanız, biraz önce tuple içerisinde gördüklerinizi ekrana tek tek verebilirsiniz. Mesela az önce 'en son ne zaman ona erişildi' tarzında bir merakımız olmuştu. Ona bir bakalım.

'st_atime' son erişilme tarihini gösterir. Açılımı, "last access time" şeklindedir. Evet, erişebildik ancak buradan hiçbir şey anlamıyoruz.

Bu noktada datetime modülünden faydalanabiliriz diye düşünüyorum.

Modülü import ettikten sonra datetime.fromtimestamp() dedim ve tarihi normal, okunabilir bir şekilde elde ettim. Diğer detayları okumak için: 'datetime'. Eğer isterseniz diğer özellikleri de araştırıp deneyebilirsiniz.

Bir de 'en son ne zaman değiştirildi' diye bir merakımız da oluşmuştu, onu da göstereyim.

Bu da, st_mtime. Açılımı "last modification time" şeklindedir.

os.path.exist()

'path' kelimesi 'yol, dizin yolu' anlamına gelirken 'exist' kelimesi 'var, mevcut' anlamına gelir. Bu fonksiyonu kullandığımız zaman içine vereceğimiz parametrenin orada olup olmadığını kontrol edecektir. Eğer dosya veya klasör orada ise 'True', değilse 'False' değer döndürecektir.

Normalde benim 'denemeKlasoru' isimli bir klasörüm ve onun içinde 'deneme.txt' isimli bir dosyam mevcut. Gördüğünüz üzere bu ikisini arattığım zaman True değerini alıyorum. Ancak var olmayanları arattığımda False değerini alıyorum.

os.path.isfile() ve os.path.isdir()

isfile() fonksiyonu, aratılan şeyin bir dosya olup olmadığını söyler. Eğer aratılan şey bir dosya ise True, klasör ise False değerini döndürür.

isdir() fonksiyonu, aratılan şeyin bir klasör olup olmadığını söyler. Eğer aratılan şey bir klasör ise True, dosya ise False değerini döndürür.

os.walk()

Şimdi size çok manyak bir şey göstereceğim; os.walk(). Buradaki 'walk' kelimesi 'yürümek' anlamına gelir. Bu fonksiyon, ona verdiğiniz lokasyondaki bütün klasörleri tek tek gezer ve içerisindeki klasör ve dosyaları listeler. Örneğin parametre olarak C:\Python verirsek ilk önce C:\Python içindeki tüm klasör ve dosyaları yazdırır. Daha sonra C:\Python içerisinde klasör varsa o klasörlere de, orada klasör kalmayana kadar teker teker girer ve içerisinde bulunanları gösterir. Bakın şimdi.

Renk uyumuna dikkat edin lütfen. Az önce anlattıklarımı da tekrar okuyarak bunları bağdaştırın ve uygulama yapın.

Diyelim ki bilgisayarda bir şey arıyorsunuz ama nerede olduğunu bilmiyorsunuz. Bunun için ne yaparsınız?

Normalde örneğin Linux'ta bunu bu şekilde yaparsınız:

find / -name <dosya veya klasör adı>

ya da

find /home -name <dosya veya klasör adı>

Yani oldukça kolaydır. Ancak şimdi, walk() fonksiyonunu kullanacağız. Ben, 'test.txt' isimli bir dosya oluşturdum ve bunu C:\Users\Public\Documents içerisine koydum. Sonra mesela aylar geçti ve ben onu bir türlü bulamadım. O yüzden şöyle bir kod yazdım.

walk() fonksiyonu, verdiğimiz lokasyona girince klasörün yolunu, o yol içerisindeki klasörlerin adını ve o yol içerisindeki klasörlerin içinde bulunan dosya isimlerini yazdırıyordu. Buradaki for döngüsünün mantığı budur. Sonrasında ben, taradığı bu lokasyon ve isimler arasından fileNames yani dosya isimlerine odaklandım. Bunun için bir for döngüsü daha açtım ve içerisine şunu dedim: "Eğer dosya isimlerinden herhangi birinin adı test.txt ise bana onun yolunu göster ve programdan çık."

Bu kod, bütün C: klasörünü arayacak ve 'test.txt' dosyasını bulana kadar çalışmaya devam edecektir. Eğer C: içinde test.txt yok ise C: klasörü içindeki son klasör tarandıktan sonra program kapanacaktır. Demek ki birkaç satırda harikalar yaratabiliyoruz.

os.walk() fonksiyonunun içine bakın. Normal şartlarda oraya C:\ yazıyorduk. Ancak burada, kapsamak istediğimiz alan bütün C: klasörü olduğu için C:/ yazmamız gerekiyor. Eğer burada da ters slash kullanırsanız hata alırsınız.

os.path.splitext()

Bu fonksiyon, bir dosyanın uzantısını isminden ayırmaya olanak tanır. Açılımı "split extension" yani "uzantıyı ayır" şeklindedir. Bakalım.

Gördüğünüz gibi bu bir Tuple ve lokasyon ile uzantıyı birbirinden ayırmış. Peki, madem bu bir Tuple; o zaman ben index kullanamaz mıyım?

Gördüğünüz gibi birinci index'i yani uzantıyı çağırdım. Bu blog boyunca çıktısı liste [''] veya Tuple ('') olan her şeyi index ile çağırıp kullanabilirsiniz. Örneğin listdir() fonksiyonunu kullanırken klasördeki dosyaları görebiliyorduk. Dikkat ettiyseniz çıktımız bir liste olarak geliyordu. Bunu index ile kullanalım.

os.system()

Bu fonksiyon ile bilgisayarı kapatabiliyor, yeniden başlatabiliyor ya da bilgisayarı kilitleyebiliyoruz. Bu işlemlere ait kodları sadece göstermekle kalacağım çünkü bilgisayarı sürekli kapatıp açmak istemiyorum. Ancak ek olarak sanal makine ile deneyebiliriz.

Windows için diğer komutları görmek isterseniz Python Shell'ine bağlanıp import os demeniz gerek. Sonrasında 'help(os.system("shtdown"))' komutunu verebilirsiniz.

Şimdi sanal makineye geçelim.

Yardım almak için sol taraftaki terminalde 'shutdown --help' dedim. Buna bağlı olarak sağ taraftaki terminalde Python Shell'ine bağlandım ve import os dedikten sonra os.system("shutdown -r") dedim. Bu, makineyi yeniden başlatan bir komuttur.  Gördüğünüz gibi hemen ardından bir görev ayarladı ve kısa süre sonra bilgisayarı yeniden başlatacağını söyledi. Ben de bu görevi yerine getirmemesi için 'os.system("shutdown -c")' dedim yani bunu iptal ettim.

Bu defa '-P' parametresini kullanarak makineyi tamamen kapatmasını istedim. Linux, yine kısa zaman sonrası için bir görev tanımladı ve ben bunu iptal ettim. Kısacası os.system("shutdown -P") derseniz makineyi kapatacaktır.

Makineyi, kodu yazar yazmaz kapatmak için ne yapabiliriz?

os.system("shutdown -h now") dememiz yeterli olacaktır. Ayrıca dikkat edin; sol taraftaki terminalde bulunan -h parametresi için "--poweroff komutuna eşdeğerdir" tarzında bir şey de yazıyor. O zaman --poweroff yazmayı deneyelim.

Gerçekten de öyle. Tek farkı, yine bir görev tanımlıyor olmasıdır. os.system("shutdown -c") yazmazsanız orada yazan saat geldiğinde makine kapanacaktır.


Yayınlanma Tarihi: 2022-11-25 20:38:08

Son Düzenleme Tarihi: 2022-11-27 19:06:40