簡體   English   中英

使用 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/

所以實際上我現在的問題是雙重的:

  1. 如何使用os.path__file__查看上一級目錄。 換句話說,我希望/Users/hobbes3/Sites/mysite/mysite/settings.py使用相對路徑查找/Users/hobbes3/Sites/mysite/templates
  2. 我應該在項目/User/hobbes3/Sites/mysite級別還是/User/hobbes3/Sites/mysite/mysite保留template文件夾(具有跨應用程序模板,如adminregistration等)?
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
  • 如果 pip 作為 sdist 分發(但不是內置輪子),則需要MANIFEST.in
  • 不適用於相對導入(即未安裝)
  • 由於 webapps 的運行方式,出於理智考慮,它們通常被明智地忽略

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM