![](/img/trans.png)
[英]Go up a directory using \.. in string path - Python os.path
[英]Using Python's os.path, how do I go up one directory?
我最近將 Django 從 v1.3.1 升級到 v1.4。
在我的舊settings.py
我有
TEMPLATE_DIRS = (
os.path.join(os.path.dirname( __file__ ), 'templates').replace('\\', '/'),
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
這將指向/Users/hobbes3/Sites/mysite/templates
,但由於 Django v1.4 將項目文件夾移動到與應用程序文件夾相同的級別,我的settings.py
文件現在位於/Users/hobbes3/Sites/mysite/mysite/
而不是/Users/hobbes3/Sites/mysite/
。
所以實際上我現在的問題是雙重的:
os.path
從__file__
查看上一級目錄。 換句話說,我希望/Users/hobbes3/Sites/mysite/mysite/settings.py
使用相對路徑查找/Users/hobbes3/Sites/mysite/templates
。/User/hobbes3/Sites/mysite
級別還是/User/hobbes3/Sites/mysite/mysite
保留template
文件夾(具有跨應用程序模板,如admin
、 registration
等)?os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))
至於模板文件夾應該放在哪里,我不知道,因為 Django 1.4 剛剛出來,我還沒有看過它。 您可能應該在 SE 上提出另一個問題來解決該問題。
您還可以使用normpath
來清理路徑,而不是abspath
。 但是,在這種情況下,Django 需要絕對路徑而不是相對路徑。
對於跨平台兼容性,請使用os.pardir
而不是'..'
。
要獲取文件的文件夾,只需使用:
os.path.dirname(path)
要獲取文件夾,只需再次使用os.path.dirname
os.path.dirname(os.path.dirname(path))
您可能想檢查__file__
是否是符號鏈接:
if os.path.islink(__file__): path = os.readlink (__file__)
如果您使用 Python 3.4 或更新版本,向上移動多個目錄的便捷方法是pathlib
:
from pathlib import Path
full_path = "path/to/directory"
str(Path(full_path).parents[0]) # "path/to"
str(Path(full_path).parents[1]) # "path"
str(Path(full_path).parents[2]) # "."
你想要的正是這個:
BASE_DIR = os.path.join( os.path.dirname( __file__ ), '..' )
就個人而言,我會采用函數方法
def get_parent_dir(directory):
import os
return os.path.dirname(directory)
current_dirs_parent = get_parent_dir(os.getcwd())
我認為最簡單的方法就是重用 dirname() 這樣你就可以調用
os.path.dirname(os.path.dirname( __file__ ))
如果您的文件位於 /Users/hobbes3/Sites/mysite/templates/method.py
這將返回“/Users/hobbes3/Sites/mysite”
from os.path import dirname, realpath, join
join(dirname(realpath(dirname(__file__))), 'templates')
更新:
如果您碰巧通過符號鏈接“復制” settings.py
,@forivall 的答案會更好:
~user/
project1/
mysite/
settings.py
templates/
wrong.html
project2/
mysite/
settings.py -> ~user/project1/settings.py
templates/
right.html
上面的方法將“看到” wrong.html
而@forivall 的方法將看到right.html
在沒有符號鏈接的情況下,兩個答案是相同的。
這對於您想要向上移動 x 文件夾的其他情況可能很有用。 只需運行walk_up_folder(path, 6)
即可上 6 個文件夾。
def walk_up_folder(path, depth=1):
_cur_depth = 1
while _cur_depth < depth:
path = os.path.dirname(path)
_cur_depth += 1
return path
向上移動n
文件夾... run up(n)
import os
def up(n, nth_dir=os.getcwd()):
while n != 0:
nth_dir = os.path.dirname(nth_dir)
n -= 1
return nth_dir
對於像我這樣的偏執狂,我更喜歡這個
TEMPLATE_DIRS = (
__file__.rsplit('/', 2)[0] + '/templates',
)
如果您更喜歡單行獲取父目錄,我建議這樣做:
import os
parent_dir = os.path.split(os.getcwd())[0]
os.path.split()
方法返回一個元組 (head, tail),其中 tail 是最后一個斜杠之后的所有內容。 所以第一個索引是絕對路徑的父級。
當然:只需使用os.chdir(..)
。
使用os.path
我們可以像這樣向上移動一個目錄
one_directory_up_path = os.path.dirname('.')
找到您想要的目錄后,您還可以加入其他文件/目錄路徑
other_image_path = os.path.join(one_directory_up_path, 'other.jpg')
從工作目錄上一級
import os
os.path.dirname(os.getcwd())
或從當前目錄
import os
os.path.dirname('current path')
從當前文件路徑,您可以使用:
os.path.join(os.path.dirname(__file__),'..','img','banner.png')
我很驚訝 os 庫沒有直接處理路徑字符串中任意數量的“..”父目錄標記。 這是一個快速而骯臟的函數,它將為您提供來自相對路徑的絕對路徑字符串:
def get_abs_from_relpath(relpath:str) -> str:
ap = os.path.abspath(__file__).split("/")[:-1]
sp = relpath.split("/")
sp_start_index = 0
for slug in sp:
if slug == "..":
ap.pop(-1)
sp_start_index += 1
else:
return "/".join(ap+sp[sp_start_index:])
你可以像這樣用 open() 調用它:
with open(get_abs_from_relpath('../../../somedir/myfile.txt')) as f:
foo = f.read()
不是一個答案,而是一個很長的切線評論,可能應該做出,因為有人可能會誤入歧途......
語法os.path.join( os.path.dirname( __file__ ), 'foo.txt')
來獲取與運行 python 文件相同的文件夾中的文件不是包的“建議”解決方案,而是包數據出於幾個原因,例如在 zip 打包的包或更復雜的文件系統中,它是首選。
pkg_resources.read_text(__package__, 'foo.txt')
是以前推薦的解決方案,但會在某個時候被刪除,並且importlib.resources.read_text(__package__, 'foo.txt')
是推薦的方式 - 請參閱https:// docs.python.org/3/library/importlib.html#module-importlib.resources獲取許多選項。 然而,這
setup.py
文件中需要include_package_data=True
和帶有Dict[str, List[str]
的package_data
MANIFEST.in
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.