Python'da bir dosyanın içeriğini okumanın / yazmanın en kolay yolu


83

Ruby'de, kullanarak bir dosyadan okuyabilirsiniz s = File.read(filename). Python'da bildiğim en kısa ve en net olanı

with open(filename) as f:
    s = f.read()

Bunu daha da kısaltacak (tercihen bir satır) ve daha okunaklı hale getirecek başka bir yol var mı?

Not: Başlangıçta soruyu "bunu tek bir kod satırında yapmak" şeklinde ifade ettim. S.Lott'un işaret ettiği gibi, daha kısa olmak, daha okunaklı anlamına gelmez. Bu yüzden ne demek istediğimi açıklığa kavuşturmak için sorumu yeniden ifade ettim. Ruby kodunun daha iyi ve daha okunabilir olduğunu düşünüyorum çünkü tek satıra karşı iki satır olması değil (bu da önemli olsa da), aynı zamanda bir örnek yönteminin aksine, dosyayı kimin kapattığına dair hiçbir soru sormayan bir sınıf yöntemi olduğu için, bir istisna ortaya çıksa bile kapatıldığından nasıl emin olunur, vb. Aşağıdaki cevaplarda belirtildiği gibi, dosyanızı kapatmak için GC'ye güvenebilirsiniz (böylece bunu tek satırlık bir hale getirebilirsiniz), ancak bu, kodu daha da kötüleştirir daha kısa olmasına rağmen. Sadece taşınabilir olmamakla değil, belirsizleştirerek.


7
Kendi işlevinizi yaratın. Sonra içeriği almak için kullanabilirsiniz. Çağrı tek hat olacaktır.
Felix Kling

1
Merak ediyorum, Ruby ifadesi dosyayı da kapatıyor mu?
dheerosaur

8
-1: Kod golfünde kimse kazanmaz.
S.Lott

4
Sorum benim için mantıklı. Bu iki satırı yazmanın daha iyi bir yolunu bulmaya çalışıyorum (2.5'teki withifadeden 4 satır önce ). Belki bir yolu vardır, belki yoktur. Her zaman öğrenmeye çalışabilirim, değil mi? Beğenmediyseniz, olumsuz oy verin ve devam edin. :)
ibz

1
Yararı File.readlines("filename"), adı verilen bir dosyanın içeriğini okumasıdır. Kanıtın herhangi bir yerinde dosya tanıtıcı, tanımlayıcı veya nesne yoktur. Gördüğüm tüm Python "eşdeğerleri" arasında açık bir açma / kapama (veya daha kötüsü, açık bir kapatma gerektiren örtük bir açma) var.
Mark Reed

Yanıtlar:


12

Kitaplıkları kullanmaya açıksanız, çatallı yolu (easy_install veya pip ile) yüklemeyi deneyin .

O zaman şunları yapabilirsiniz:

from path import path
s = path(filename).bytes()

Bu kütüphane oldukça yenidir, ancak yıllardır Python'da dolaşan ve epeyce kullanılan bir kütüphanenin çatalı. Bu kütüphaneyi yıllar önce bulduğumdan beri, nadiren os.pathveya open()daha fazlasını kullanıyorum.


Güzel bir kitaplığa benziyor. Sadece bunun için kurmayacağım, ama aklımda tutacağım.
ibz

1
Tam bir hack olduğu için neden kabul edilen cevap olduğunu anlamıyorum!
nikolay

Windows'ta pip 18.6 tarafından kurulan çatallı yol v0.2.3, Python 3.6.4 ile uyumlu değildir. Görünüşe göre sekizlik sabitler için kullanılan format (örneğin 0777yerine 0o0777) mevcut python sürümüm tarafından desteklenmiyor.
Christoffer Soop

Eyal Levin'in cevabına +1 . Bunu 8 yıl önce ilk olarak yanıtladığımda pathlib veya pathlib2 olsaydı, çatallı yol yerine onlardan söz ederdim. Yıllardır çatallı yolu kullanmadım.
2018,

151
with open('x.py') as f: s = f.read()

*** sırıtıyor ***


1
OP'nin başlangıçta yaptığı gibi yazmamak için hiçbir neden yok. Niyet açıktı.
Mark Tolonen

43

Bu, yukarıdakiyle aynıdır, ancak hataları işlemez:

s = open(filename, 'r').read()

21
Pek değil, seninki dosyayı açık bırakıyor.
ibz

3
CPython uygulaması, referans sayısı sıfıra gittiğinde dosyayı kapatır, ancak bu güvenilmemesi gereken bir uygulama detayıdır.
Mark Tolonen

1
Bu, hataları idare eder; her zamanki gibi bir istisna atılacaktır. Bu mu değil "açık dosyayı bırakmak", ancak dosya yakın olması nedeni ne yapabilir olduğunu gecikmeli GC uygulamaya bağlı. Bu bir sorun olabilir (Windows'ta kilitleme ve örneğin, birçok dosya üzerinde döngü yapılıyorsa FD sınırları), ancak bu, dosyayı açık bırakmaktan (örneğin, dosyayı sızdırmaktan) çok farklıdır.
Glenn Maynard

11
Tasarım hedefiniz "bir satır kod" ise, çok fazla Perl soludunuz ve ciddi bir beyin yıkamadan kurtulma süresi planlamanız gerekiyor.
Glenn Maynard

6
Hayır, bu hiç de kafa karıştırıcı değil.
Glenn Maynard

37

Pathlib kullanın .

Python 3.5 ve üstü:

from pathlib import Path
contents = Path(file_path).read_text()

Python'un daha düşük sürümleri için pathlib2'yi kullanın :

$ pip install pathlib2

Sonra

from pathlib2 import Path
contents = Path(file_path).read_text()

Yazmak da bir o kadar kolay:

Path(file_path).write_text('my text')

18
contents = open(filename).read()

9
Ve dosyayı ne zaman kapatacaksınız?
ibz

1
@ionut bizau - open(...)Çöplerin iadesi toplandığında sanırım. Yanılıyorsam biri beni düzeltsin.
detly

1
Bunu yapmanın en kısa yolu budur. neden oy almadığını bilmiyorum.
Pritesh Acharya

10

Bu Perl değil; birden çok satırlık kodu tek bir satıra zorla sığdırmak istemezsiniz. Bir işlev yazın, ardından işlevi çağırmak bir satır kod alır.

def read_file(fn):
    """
    >>> import os
    >>> fn = "/tmp/testfile.%i" % os.getpid()
    >>> open(fn, "w+").write("testing")
    >>> read_file(fn)
    'testing'
    >>> os.unlink(fn)
    >>> read_file("/nonexistant")
    Traceback (most recent call last):
        ...
    IOError: [Errno 2] No such file or directory: '/nonexistant'
    """
    with open(fn) as f:
        return f.read()

if __name__ == "__main__":
    import doctest
    doctest.testmod()

5

Yavaş, çirkin, platforma özgü ... ama tek satırlık ;-)

import subprocess

contents = subprocess.Popen('cat %s' % filename, shell = True, stdout = subprocess.PIPE).communicate()[0]

4
aaaaaaaaaaargh! (asgari karakter sınırını karşılamak için fazla 'a)
Peter Gibson

6
Kesinlikle sorunun özüne uyuyor ... Python'un Bash'e benzemesi için yanlış kullanılması, onu Ruby veya Perl'e benzetmekten daha kötü değildir.
detly

3

Bu kadar basit:

    f=open('myfile.txt')
    s=f.read()
    f.close()

Ve "s" içeriğiyle istediğinizi yapın


-1
contents = open(filename)

Bu size jeneratör verir, böylece değerleri bir yere kaydetmeniz gerekir veya

contents = [line for line in open(filename)]

Bu, açıkça kapatmayı listelemek için kaydetme işleminin mümkün olmadığını (en azından Python bilgimle) yapar.


1
ve içindekiler = '' .join (açık (dosya adı) satır için satır) orijinal dosya içeriğine
sahipsiniz

Bir şekilde bir dosya kullanarak yineleyici yok değil (gibi deterministically dosyayı kapatın withyapar). Yapamaz, çünkü yineleme bittikten sonra dosyayı aramak ve yeniden okumaya başlamak hala geçerlidir, bu da yineleme dosyayı kapatırsa işe yaramaz.
Glenn Maynard

@Glenn Ama jeneratörü benim örneğim gibi liste anlamada kullanırsanız, adı olmadığı için kapatmanız bile mümkün değil.
Tony Veijalainen

"Kapatmak mümkün değil" dir değil "kapatmak gerekmez" ile aynıdır.
Glenn Maynard

Belki öyledir, ancak bu dosya tanıtıcısına listenin içinden nasıl erişeceğimi bilemezdim. Python'da belki 'tüm dosya g / ç tamamlandı, tüm program açılmış dosyaları kapat' komutu mu olmalı? Veya dosya nesneleri için açık gc yeterli olabilir mi? Dosya tanıtıcısı, liste anlama ayrı bir kapsam olduğundan kapsam dışındadır.
Tony Veijalainen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.