Làm thế nào để có được vị trí thư mục cha


129

mã này có được các mẫu / blog1 / page.html trong b.py:

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

nhưng tôi muốn có được vị trí thư mục cha mẹ:

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

và làm thế nào để có được vị trí aParent

cảm ơn

đã cập nhật:

đúng rồi đó:

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

hoặc là

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

2
Vì vậy, bạn muốn có được blog1hay a? Và tập tin hiện tại của bạn nằm ở đâu?
Felix Kling

bạn có hiểu mã của bạn đang làm gì không?
SilentGhost

1
có, nó nhận được các mẫu / blog1 / page.html
zjm1126

os.path.join('templates', 'blog1/page.html')có vẻ lạ đối với tôi Bạn đang trộn mọi thứ lên. Hoặc là os.path.join('templates', 'blog1', 'page.html')hoặc 'templates/blog1/page.html'. Và dễ dàng hơn nhiều os.path.abspath(os.path.join('templates', 'blog1', 'page.html'))khi đó
Felix Kling

1
@zjm: không, bạn không trang đó. Đây không phải là hộp đen mà bạn chỉ có thể sử dụng để lấy tệp mẫu. Nó thực hiện một loạt các bước nhỏ tầm thường và nếu bạn có thể hiểu chúng, bạn sẽ không có câu hỏi này.
SilentGhost

Câu trả lời:


171

Bạn có thể áp dụng dirname nhiều lần để leo lên cao hơn : dirname(dirname(file)). Điều này chỉ có thể đi xa như gói gốc, tuy nhiên. Nếu đây là một vấn đề, sử dụng os.path.abspath: dirname(dirname(abspath(file))).


37
Tôi biết OP biết về dirname. Mọi người đều không rõ việc áp dụng dirname vào thư mục sẽ mang lại thư mục mẹ.
Marcelo Cantos

4
dirnamekhông KHÔNG luôn luôn trở về thư mục mẹ; twitter.com/#!/ActiveState/status/671049326788608
Sridhar Ratnakumar

2
@Sridhar: Điều đó phụ thuộc vào quan điểm của bạn; Tôi xem xét một đường dẫn kết thúc bằng /không đại diện cho chính mục nhập thư mục lá, nhưng nội dung của nó, đó là lý do tại sao, ví dụ, mv xxx yyy/không thành công nếu yyykhông phải là thư mục có sẵn. Trong mọi trường hợp, ngay cả khi chúng tôi đưa ra quan điểm của bạn như đã cho, điều đó không liên quan trong bối cảnh câu trả lời của tôi. Cả filecũng không phải kết quả của dirnametừng sẽ kết thúc trong một /.
Marcelo Cantos

1
Sửa chữa nhỏ: dirnamecó thể trở lại '/', kết thúc rõ ràng trong a /. Đó là ngoại lệ duy nhất, AFAIK.
Marcelo Cantos

55

os.path.abspathkhông xác thực bất cứ điều gì, vì vậy nếu chúng tôi đã nối thêm các chuỗi vào __file__thì không cần phải bận tâm dirnamehoặc tham gia hoặc bất kỳ điều nào trong số đó. Chỉ cần coi __file__như một thư mục và bắt đầu leo ​​lên:

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

Đó là ít phức tạp hơn os.path.abspath(os.path.join(os.path.dirname(__file__),".."))và về quản lý như dirname(dirname(__file__)). Leo hơn hai cấp độ bắt đầu trở nên lố bịch.

Nhưng, vì chúng tôi biết có bao nhiêu cấp độ để leo lên, chúng tôi có thể làm sạch điều này với một chức năng nhỏ đơn giản:

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
Điều này thật tuyệt, nhưng cũng thật tuyệt nếu thư viện tiêu chuẩn đã thêm một chức năng tiện lợi để thực hiện điều này ... không muốn đến SO mỗi khi tôi cần func
gradi3nt

4
Sẽ os.path.abspath(os.path.join(__file__, "..", "..")di động hơn?
SlowD

40

Sử dụng đường dẫn tương đối với pathlibmô-đun trong Python 3.4+:

from pathlib import Path

Path(__file__).parent

Bạn có thể sử dụng nhiều cuộc gọi parentđể đi xa hơn trong đường dẫn:

Path(__file__).parent.parent

Thay thế cho việc chỉ định parenthai lần, bạn có thể sử dụng:

Path(__file__).parents[1]

2
Nếu bạn cần đường dẫn dưới dạng chuỗi vì bạn muốn sửa đổi nó, bạn chỉ có thể sử dụng str(Path(__file__).parent).
Phi

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

Nên cho bạn đường dẫn đến a.

Nhưng nếu b.pylà tệp hiện đang được thực thi, thì bạn có thể đạt được điều tương tự bằng cách thực hiện

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

1
o, tôi biết, bạn đã đúng, và tôi muốn lấy thư mục mẹ của a. làm thế nào để có được nó
zjm1126

@ zjm1126: Xem câu trả lời của Marcelo Cantos. Áp dụng dirname()hai lần. Tất cả mọi thứ bạn cần bây giờ nên có trên trang web này.
Felix Kling

9

os.pardirlà một cách tốt hơn cho ../và dễ đọc hơn.

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

Điều này sẽ trả về đường dẫn cha của cho_path


5

Một cách đơn giản có thể là:

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

3

Có thể tham gia hai ..thư mục, để có được cha mẹ của thư mục cha mẹ?

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

3

Sử dụng như sau để chuyển đến thư mục trước:

os.chdir(os.pardir)

Nếu bạn cần nhiều lần nhảy, một giải pháp tốt và dễ dàng sẽ là sử dụng một công cụ trang trí đơn giản trong trường hợp này.


1

Đây là một giải pháp tương đối đơn giản khác:

  • không sử dụng dirname()(không hoạt động như mong đợi trên các đối số một cấp như "file.txt" hoặc cha mẹ tương đối như "..")
  • không sử dụng abspath()(tránh mọi giả định về thư mục làm việc hiện tại) mà thay vào đó giữ nguyên đặc tính tương đối của các đường dẫn

nó chỉ sử dụng normpathjoin:

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)

Kết quả:

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

0

Tôi nghĩ rằng sử dụng này là tốt hơn:

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'

Không hoàn toàn, nó phụ thuộc vào hệ điều hành (sẽ không hoạt động trên Windows). Ngoài ra, nó không cho phép sử dụng các đường dẫn tương đối.
kgadek

Đó là một giải pháp khủng khiếp. Không hoạt động cho tất cả các hệ điều hành
web.learner

0

Tôi đã thử:

import os
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), os.pardir))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.