"İmport os.path" veya "import os" kullanmalı mıyım?


139

Göre resmi belgeler , os.pathbir modüldür. Peki, onu ithal etmenin tercih edilen yolu nedir?

# Should I always import it explicitly?
import os.path

Veya...

# Is importing os enough?
import os

Lütfen " osbenim için işleri içe aktarma" yanıtını vermeyin . Biliyorum, şu anda benim için de çalışıyor (Python 2.6'dan itibaren). Bilmek istediğim, bu konuda herhangi bir resmi öneri. Bu soruyu cevaplarsanız, lütfen referanslarınızı gönderin .

Yanıtlar:


157

os.pathkomik bir şekilde çalışır. Görünüşe osbir altmodülün bir paket olmalı path, ama gerçekte osile büyü yapar normal modülüdür sys.modulesenjekte etmek os.path. İşte olanlar:

  • Python başladığında, içine bir grup modül yükler sys.modules. Komut dosyanızdaki herhangi bir isme bağlı değildir, ancak önceden oluşturulmuş modüllere bir şekilde içe aktardığınızda erişebilirsiniz.

    • sys.modulesmodüllerin önbelleğe alındığı bir diksiyondur. Bir modülü içe aktardığınızda, daha önce bir yere aktarılmışsa, örneği depolar sys.modules.
  • osPython başlatıldığında yüklenen modüller arasındadır. pathÖzniteliğini işletim sistemine özgü bir yol modülüne atar .

  • Bir alt modül gibi sys.modules['os.path'] = path" import os.path" yapabilmeniz için enjekte eder .

Aklıma eğilimindedir os.patholarak kullanmak istediğim bir modül yerine bir şey osmodülü öyle değil, yani rağmen gerçekten denilen bir paketin bir alt modül os, bunu biridir gibi çeşit içe ve hep yapmakimport os.path . Bu, os.pathbelgelenme şekliyle tutarlıdır .


Bu arada, bu tür bir yapı Python programcılarının modüller ve paketler ve kod organizasyonu hakkında erken kafa karışıklığına yol açtığını düşünüyorum. Bu gerçekten iki nedenden dolayı

  1. osBir paket olarak düşünürseniz import osve alt modüle erişebildiğinizi ve erişebildiğinizi os.pathbiliyorsanız, daha sonra yapamayacağınız import twistedve twisted.spreadiçe aktarmadan otomatik olarak erişemediğinizde şaşırabilirsiniz .

  2. Bu os.namenormal bir şey, bir dize ve os.pathbir modül olduğu kafa karıştırıcı . Paketlerimi her zaman boş __init__.pydosyalarla yapılandırırım, böylece aynı seviyede her zaman bir tür şeyim olur: bir modül / paket veya başka şeyler. Birkaç büyük Python projesi bu yaklaşımı benimser ve bu da daha yapılandırılmış kod yapma eğilimindedir.


Mükemmel, çok bilgilendirici cevap! Tebrikler! Soruyu doğrudan cevaplamasa da birçok yararlı detayı var. Ancak "Bu işlem yolunun belgelenmesi ile tutarlıdır" hakkında ayrıntı verebilir misiniz? Chris Hulan'ın dediği gibi os.walk () örneği os.path yerine sadece os ithal ediyor.
Denilson Sá Maia

3
@Denilson, Doğrudan bir cevap içeriyor: Her zaman import os.pathkendimi yaparım ve bunun daha güzel bir yol olduğunu düşünüyorum. "Bu, os.path'in nasıl belgelendiğiyle tutarlıdır" derken, docs.python.org/library/os.path.html adresindeki dokümanlarda kendi sayfası verildiğini kastediyorum .
Mike Graham

1
Vay be, os.pygerçekten enjekte ediyor sys.modules['os.path']. Bu yüzden from os.path import somethingaslında çalışıyor. Bunun ne zaman tanıtıldığını ve kaynağı kontrol ettiğini merak ettim. Eğlenceli gerçek: Bu 1999'dan, ilk olarak Python 1.5.2'ye dahil edildi. Orijinal taahhüt burada .
Bluehorn

29

Gereğince PEP-20 Tim Peters tarafından ve "Okunabilirlik sayımları" "Açık örtülü daha iyidir". osModülden ihtiyacınız olan her şey altındaysa os.path, import os.pathdaha açık olurdu ve başkalarına gerçekten neye önem verdiğinizi bildirin.

Benzer şekilde, PEP-20 de "Basit karmaşık olmaktan daha iyidir" der, bu nedenle daha genel osşemsiyenin altında bulunan şeylere de ihtiyacınız varsa import ostercih edilir.


2
import osGerçekten "basit" olmanın nasıl anlamlı olduğunu hiçbir şekilde anlamıyorum . Basit! = Kısa.
Mike Graham

14
Ben daha işaret etmeye çalışıyordum import os veimport os.path örneğin gerekirse bir daft olduğunu os.getcwd()veos.path.isfile()
Nick T

15

Kesin cevap: import osve kullanımı os.path. import os.pathdoğrudan değil .

Modülün belgelerinden:

>>> import os
>>> help(os.path)
...
Instead of importing this module directly, import os and refer to
this module as os.path.  The "os.path" name is an alias for this
module on Posix systems; on other systems (e.g. Mac, Windows),
os.path provides the same operations in a manner specific to that
platform, and is an alias to another module (e.g. macpath, ntpath).
...

13
Bunun var olmayan bir os.pathmodül için dokümanlar değil, için olduğunu unutmayın posixpath.
wRAR

18
Oldukça yanıltıcı olmasına rağmen, öğretinin yorumlanması gerektiği hiç de öyle değil. Cümle unutmayın "Instead of importing this module directly, import os and refer to this module as os.path."bulunan posixpath.py(ya da macpath.py, ntpath.pyvs.). Onların ne anlama geldiğini import posixpath(ki işe yarıyor) değil os, daha iyi taşınabilirlik için modülü üzerinden alması gerektiğine eminim . Ben tercih import osya import os.pathda tercih konusunda bir öneri vermek niyetinde olduğunu sanmıyorum .
flornquake

1
@Flornquake'in yorumunun çoğuna katılıyorum ama son cümleyi kabul etmiyorum. Hem posixpath.py hem de ntpath.py "işletim sistemini içe aktarın ve bu modüle os.path" olarak bakın. "Os.path dosyasını içe aktarın ve bu modüle os.path olarak bakın" demiyorlar. macpath.py'nin bu konuda hiçbir şeyi yok.
Pete Forman

3
Bu, bu işaretçiyi içeren bir belgenin nasıl yanıltıcı olabileceğini gösteren iyi bir örnektir : D
Cyker

7

İlginçtir ki, os.path dosyasını almak tüm işletim sistemlerini içe aktaracaktır. etkileşimli istemde aşağıdakileri deneyin:

import os.path
dir(os)

Sonuç, işletim sistemini yeni içe aktardığınız gibi olacaktır. Çünkü os.path, hangi işletim sistemine sahip olduğunuza bağlı olarak farklı bir modüle atıfta bulunacaktır, bu nedenle python, yol için hangi modülü yükleyeceğini belirlemek için os'u içe aktaracaktır.

referans

Bazı modüllerde söyleme import fooaçığa çıkmaz foo.bar, bu yüzden gerçekten belirli modülün tasarımına bağlıdır.


Genel olarak, sadece ihtiyacınız olan açık modülleri içe aktarmak marjinal olarak daha hızlı olmalıdır. Makinemde:

import os.path: 7.54285810068e-06 saniye

import os: 9.21904878972e-06 saniye

Bu zamanlar oldukça önemsiz olacak kadar yakın. Programınızın osşimdi veya daha sonra başka modüller kullanması gerekebilir , bu nedenle genellikle iki mikrosaniyeden feda etmek ve import osbu hatayı daha sonra önlemek için kullanmak mantıklıdır . Genellikle os'u bir bütün olarak içe aktarmakla yanlıyorum, ancak bazılarının neden import os.pathteknik olarak daha verimli olmasını tercih edeceğini ve osmodülün kullanılması gereken tek parça olan kod okuyucularına iletmeyi tercih edebileceğini görebiliyorum . Aslında aklımdaki bir stil sorusu ile kaynaşır.


2
from os import pathhız sorunu söz konusuysa yol çağrılarını daha da hızlı hale getirir.
Justin Peel

Pitonik olmak, açık olmak örtük olmaktan daha iyidir. Gerçekte, kullanıcının yalnızca os.path veya os içinde birden fazla modül kullanıp kullanamayacağını gerçekten kullanıcı tarafından yapılan karar çağrısı olduğunu düşünüyorum. Belki bir yöntem diğerine karşı felsefenizle daha uyumludur?
Andrew Kou

23
Bu zamanlama şimdiye kadar gördüğüm en erken erken optimizasyon. Bu hiç kimsenin darboğazı olmadı ve buradaki zaman, birisinin nasıl kodlaması gerektiği konusunda önemsiz.
Mike Graham

5

Sağduyu burada çalışır: osbir modül ve os.pathaynı zamanda bir modül. Kullanmak istediğiniz modülü içe aktarın:

  • osModüldeki işlevleri kullanmak isterseniz , içe aktarın os.

  • os.pathModüldeki işlevleri kullanmak isterseniz , içe aktarın os.path.

  • Her iki modülde de işlevsellik kullanmak istiyorsanız, her iki modülü de içe aktarın:

    import os
    import os.path

Referans için:


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.