Ana dizin konumu nasıl alınır


131

bu kod, b.py içindeki şablonları / blog1 / page.html'yi alır:

path = os.path.join(os.path.dirname(__file__), os.path.join('templates', 'blog1/page.html'))

ama ana dizin konumunu almak istiyorum:

aParent
   |--a
   |  |---b.py
   |      |---templates
   |              |--------blog1
   |                         |-------page.html
   |--templates
          |--------blog1
                     |-------page.html

ve aParent konumu nasıl alınır

Teşekkürler

güncellenmiş:

bu doğru:

dirname=os.path.dirname
path = os.path.join(dirname(dirname(__file__)), os.path.join('templates', 'blog1/page.html'))

veya

path = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))

2
Yani almak blog1ister amisin? Ve mevcut dosyanız nerede bulunuyor?
Felix Kling

kodunuzun ne yaptığını anlıyor musunuz?
SilentGhost

1
evet, şablonları / blog1 / page.html alır
zjm1126

os.path.join('templates', 'blog1/page.html')bana tuhaf görünüyor. Bir şeyleri karıştırıyorsun. Ya os.path.join('templates', 'blog1', 'page.html')ya da 'templates/blog1/page.html'. Ve os.path.abspath(os.path.join('templates', 'blog1', 'page.html'))o zaman çok daha kolay olurdu
Felix Kling

1
@zjm: hayır, yok olsun o sayfayı. Şablon dosyasını almak için kullanabileceğiniz bir kara kutu değil. Bir dizi önemsiz küçük adım gerçekleştirir ve eğer onları anlayabilseydiniz, bu soruyu sormazdınız.
SilentGhost

Yanıtlar:


173

Daha yüksek tırmanmaya defalarca dirname uygulayabilirsiniz: dirname(dirname(file)). Ancak bu yalnızca kök pakete kadar gidebilir. Bu bir sorun varsa, kullanın os.path.abspath: dirname(dirname(abspath(file))).


37
OP'nin bildiğini biliyorum dirname. Bir dizine dirname uygulamasının ana dizini verdiği herkes için açık değildir.
Marcelo Cantos

4
dirnameyok DEĞİL hep üst dizini döndürür; twitter.com/#!/ActiveState/status/671049326788608
Sridhar Ratnakumar

2
@Sridhar: Bu sizin bakış açınıza bağlıdır; İle biten bir yolun /yaprak dizin girişinin kendisini temsil etmediğini, ancak içeriğini temsil ettiğini düşünüyorum, bu nedenle, örneğin önceden var olan bir dizin değilse mv xxx yyy/başarısız olur yyy. Her halükarda, fikrinizi belirli olarak alsak bile, cevabım bağlamında alakasızdır. Ne filede dirnameiradenin sonucu bir ile bitmez /.
Marcelo Cantos

1
Minör düzeltme: dirnamedöndürebilir '/'açıkça biter, hangi /. Tek istisna bu, AFAIK.
Marcelo Cantos

55

os.path.abspathiçin biz zaten dizeleri ekliyorsanız eğer öyleyse, bir şey doğrulamaz __file__ile rahatsız etmek gerek yoktur dirnamekatılmadan ya da herhangi bir veya. Sadece __file__bir dizin gibi davranın ve tırmanmaya başlayın:

# climb to __file__'s parent's parent:
os.path.abspath(__file__ + "/../../")

Bu os.path.abspath(os.path.join(os.path.dirname(__file__),"..")), yönetilebilir olandan çok daha az kıvrımlı dirname(dirname(__file__)). İkiden fazla seviyeye tırmanmak gülünç olmaya başlar.

Ancak, kaç seviye tırmanacağımızı bildiğimiz için, bunu basit bir küçük işlevle temizleyebiliriz:

uppath = lambda _path, n: os.sep.join(_path.split(os.sep)[:-n])

# __file__ = "/aParent/templates/blog1/page.html"
>>> uppath(__file__, 1)
'/aParent/templates/blog1'
>>> uppath(__file__, 2)
'/aParent/templates'
>>> uppath(__file__, 3)
'/aParent'

2
Bu güzel, ancak standart kitaplık bunu başaran bir kolaylık işlevi
ekleseydi

4
Misiniz os.path.abspath(os.path.join(__file__, "..", "..")daha taşınabilir olması?
slowD

40

Kullan göreli yol ile pathlib3.4+ Python modülü:

from pathlib import Path

Path(__file__).parent

parentYolda daha ileri gitmek için birden fazla çağrı kullanabilirsiniz :

Path(__file__).parent.parent

parentİki kez belirtmeye alternatif olarak şunları kullanabilirsiniz:

Path(__file__).parents[1]

2
Yolu değiştirmek istediğiniz için dizge olarak ihtiyacınız varsa, kullanabilirsiniz str(Path(__file__).parent).
Philipp

12
os.path.dirname(os.path.abspath(__file__))

Sana yolu vermeli a.

Ancak b.pyşu anda yürütülen dosya ise, aynı şeyi yalnızca

os.path.abspath(os.path.join('templates', 'blog1', 'page.html'))

1
o, biliyorum, haklısın ve a'nın üst klasörünü almak istiyorum. nasıl
edinilir

@ zjm1126: Marcelo Cantos'un cevabına bakın. dirname()İki kez uygulayın . Şimdi ihtiyacınız olan her şey bu sitede olmalı.
Felix Kling

9

os.pardiriçin daha iyi ../ve daha okunaklı bir yoldur .

import os
print os.path.abspath(os.path.join(given_path, os.pardir))  

Bu, verilen_ yolun üst yolunu döndürecektir


5

Basit bir yol şunlar olabilir:

import os
current_dir =  os.path.abspath(os.path.dirname(__file__))
parent_dir = os.path.abspath(current_dir + "/../")
print parent_dir

3

..Üst klasörün üstünü almak için iki klasöre katılabilir mi?

path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"..",".."))

3

Önceki klasöre atlamak için aşağıdakileri kullanın:

os.chdir(os.pardir)

Birden fazla sıçramaya ihtiyacınız varsa, bu durumda basit bir dekoratör kullanmak iyi ve kolay bir çözüm olacaktır.


1

İşte nispeten basit bir çözüm:

  • kullanmaz dirname()("dosya.txt" gibi tek seviyeli bağımsız değişkenlerde veya ".." gibi göreli ebeveynlerde beklendiği gibi çalışmaz)
  • kullanmaz abspath()(geçerli çalışma dizini hakkında herhangi bir varsayımdan kaçınarak), bunun yerine yolların göreceli karakterini korur

sadece kullanır normpathve join:

def parent(p):
    return os.path.normpath(os.path.join(p, os.path.pardir))

# Example:
for p in ['foo', 'foo/bar/baz', 'with/trailing/slash/', 
        'dir/file.txt', '../up/', '/abs/path']:
    print parent(p)

Sonuç:

.
foo/bar
with/trailing
dir
..
/abs

0

Bunu kullanmanın daha iyi olduğunu düşünüyorum:

os.path.realpath(__file__).rsplit('/', X)[0]


In [1]: __file__ = "/aParent/templates/blog1/page.html"

In [2]: os.path.realpath(__file__).rsplit('/', 3)[0]
Out[3]: '/aParent'

In [4]: __file__ = "/aParent/templates/blog1/page.html"

In [5]: os.path.realpath(__file__).rsplit('/', 1)[0]
Out[6]: '/aParent/templates/blog1'

In [7]: os.path.realpath(__file__).rsplit('/', 2)[0]
Out[8]: '/aParent/templates'

In [9]: os.path.realpath(__file__).rsplit('/', 3)[0]
Out[10]: '/aParent'

Tam olarak değil, işletim sistemine bağlıdır (Windows'ta çalışmayacaktır). Ayrıca göreli yolların kullanılmasına da izin vermez.
kgadek

Bu korkunç bir çözüm. Tüm işletim sistemleri için çalışmayacak
web.learner

0

Denedim:

import os
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), os.pardir))
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.