python: lấy thư mục lên hai cấp


87

Ok ... tôi không biết mô-đun ở đâu x is, but I know that I need to get the path to the directory two levels up.

Vì vậy, có một cách thanh lịch hơn để làm:

import os
two_up = os.path.dirname(os.path.dirname(__file__))

Các giải pháp cho cả Python 2 và 3 đều được hoan nghênh!


1
I think your solution is perfectly fine. A pathlib solution is a little nicer and more readable, but isn't included with Python 2.7. I'd say stick with what you've got, maybe add a comment.
jme

Có lẽ giá trị thêm pip install pathlib2tùy chọn để duy trì sự tỉnh táo trong 2.7.
jonathan

Câu trả lời:


104

Bạn có thể sử dụng pathlib. Thật không may, điều này chỉ có sẵn trong stdlib cho Python 3.4. Nếu bạn có phiên bản cũ hơn, bạn sẽ phải cài đặt một bản sao từ PyPI tại đây . Điều này sẽ dễ dàng để sử dụng pip.

from pathlib import Path

p = Path(__file__).parents[1]

print(p)
# /absolute/path/to/two/levels/up

Điều này sử dụng parentstrình tự cung cấp quyền truy cập vào các thư mục mẹ và chọn trình tự thứ hai lên.

Lưu ý rằng ptrong trường hợp này sẽ là một số dạng Pathđối tượng, với các phương thức riêng của chúng. Nếu bạn cần các đường dẫn dưới dạng chuỗi thì bạn có thể gọi strchúng.


Thats a nice answer thanks and great for py3. For py2 it is possible not any better than my initial attempt as it creates and extra dependency
jramm

16
This should not be the accepted answer as the Path class's parents is dependent upon the execution location. If you execute your __file__ from its current directory the Path class will have no parents. Either @Sebi2020's answer should be accepted, or your original method should be used. I believe your original method is more readable.
Red-Tune-84

1
You may need to do p = Path(os.path.abspath(__file__)).parents[1]
Adam Raudonis

4
@AdamRaudonis Instead of os.path.abspath, you can also use Path(__file__).resolve().parents[1]
Tulio Casagrande

7
As @Kazanz mentioned, this solution doesn't work when executing from other paths. The best solution is: p = Path(__file__).resolve().parents[1]. I also added it as an answer.
pythinker

46

Very easy:

Here is what you want:

import os.path as path

two_up =  path.abspath(path.join(__file__ ,"../.."))

8
And perhaps use os.pardir rather than ...
jme

does sys.argv[0] not return module that was run by python.exe? So this wouldn't necessary work if the module im interested in was imported from some other package..am I right here?
jramm

If you want to use it in a module instead use __file__.
Sebi2020

1
@jme do you know an OS where you get the parent directory with another string than".."???
Sebi2020

1
@ Sebi2020 Đúng, đáng chú ý là Mac OS cũ. Dưới đây là một danh sách: en.wikipedia.org/wiki/Path_(computing)
jme

22

Tôi sẽ thêm điều này chỉ để ngớ ngẩn, nhưng cũng vì nó cho những người mới biết tính hữu ích tiềm năng của các hàm răng cưa và / hoặc nhập khẩu.

Sau khi viết nó, tôi nghĩ mã này dễ đọc hơn (tức là thời gian nắm bắt ý định thấp hơn) so với các câu trả lời khác cho đến nay, và khả năng đọc (thường là) là vua.

from os.path import dirname as up

two_up = up(up(__file__))

Lưu ý: bạn chỉ muốn thực hiện loại điều này nếu mô-đun của bạn rất nhỏ hoặc gắn kết theo ngữ cảnh.


14

Giải pháp tốt nhất (cho python> = 3.4) khi thực thi từ bất kỳ thư mục nào là:

from pathlib import Path
two_up = Path(__file__).resolve().parents[1]

10

Để nâng cấp thư mục lên 2 cấp:

 import os.path as path
 two_up = path.abspath(path.join(os.getcwd(),"../.."))

4

Cá nhân tôi thấy rằng sử dụng mô-đun os là phương pháp dễ dàng nhất như được nêu bên dưới. Nếu bạn chỉ lên một cấp, hãy thay thế ('../ ..') bằng ('..').

    import os
    os.chdir('../..')

--Check:
    os.getcwd()

1
Có thể chấp nhận hardcode '/' Tôi đã mong đợi để đọc os.chdir (os.join ('..', '..'))
GreenAsJade

2

Tôi nhận thấy rằng những điều sau đây hoạt động tốt trong 2.7.x

import os
two_up = os.path.normpath(os.path.join(__file__,'../'))

1

Bạn có thể sử dụng điều này như một giải pháp chung:

import os

def getParentDir(path, level=1):
  return os.path.normpath( os.path.join(path, *([".."] * level)) )

@JanSila: có thể cụ thể hơn, tại sao nó không phải là pythonic? Đối với khả năng đọc, nó có thể có nhiều ý kiến điều này không, vâng - nhưng cuối cùng nó sử dụng các tính năng ngôn ngữ python tiêu chuẩn, xem ví dụ stackoverflow.com/questions/36901
Axel Heider

Nó hơi dày đặc, nhưng tôi không nghĩ điều này quá trừu tượng và không thể đọc được. Nó chỉ là một phiên bản tổng quát của các câu trả lời khác được đăng ở đây. Tuy nhiên, tôi muốn một thư viện chuẩn để thực hiện mọi việc mà không cần phải triển khai một hàm.
ryanjdillon

1

Việc triển khai nhiều nền tảng hơn sẽ là:

import pathlib
two_up = (pathlib.Path(__file__) / ".." / "..").resolve()

Việc sử dụng parentkhông được hỗ trợ trên Windows. Cũng cần thêm .resolve(), vào:

Tạo đường dẫn tuyệt đối, giải quyết tất cả các liên kết tượng trưng trên đường đi và cũng chuẩn hóa nó (ví dụ: biến dấu gạch chéo thành dấu gạch chéo ngược trong Windows)


2
Bạn có nguồn parentkhông hoạt động trên Windows không? Điều này dường như đã được sửa đôi khi bạn viết nhận xét này. Nó hoạt động tốt với tôi khi sử dụng Python 3.7.2 trên Windows 10.
Nathan

i could get parent working on windows 10 with python 3.6.5. Which version of python are you talking about @Zhukovgeen?
ggulgulia

@ggulgulia I believe it was 3.7
zhukovgreen

0

Assuming you want to access folder named xzy two folders up your python file. This works for me and platform independent.

".././xyz"


0

(pathlib.Path('../../') ).resolve()


Gives the path relative to the working directory not module
jramm

-1

I don't yet see a viable answer for 2.7 which doesn't require installing additional dependencies and also starts from the file's directory. It's not nice as a single-line solution, but there's nothing wrong with using the standard utilities.

import os

grandparent_dir = os.path.abspath(  # Convert into absolute path string
    os.path.join(  # Current file's grandparent directory
        os.path.join(  # Current file's parent directory
            os.path.dirname(  # Current file's directory
                os.path.abspath(__file__)  # Current file path
            ),
            os.pardir
        ),
        os.pardir
    )
)

print grandparent_dir

And to prove it works, here I start out in ~/Documents/notes just so that I show the current directory doesn't influence outcome. I put the file grandpa.py with that script in a folder called "scripts". It crawls up to the Documents dir and then to the user dir on a Mac.

(testing)AlanSE-OSX:notes AlanSE$ echo ~/Documents/scripts/grandpa.py 
/Users/alancoding/Documents/scripts/grandpa.py
(testing)AlanSE-OSX:notes AlanSE$ python2.7 ~/Documents/scripts/grandpa.py 
/Users/alancoding

This is the obvious extrapolation of the answer for the parent dir. Better to use a general solution than a less-good solution in fewer lines.

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.