使用Python的os.path,我如何上一个目录?

hob*_*es3 189 python django

我最近将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.
)
Run Code Online (Sandbox Code Playgroud)

这将指向/Users/hobbes3/Sites/mysite/templates,但由于Django v1.4将项目文件夹移动到与app文件夹相同的级别,我的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. 我应该保持template(其具有跨应用程序模板,如文件夹admin,registration在项目等)/User/hobbes3/Sites/mysite水平或在/User/hobbes3/Sites/mysite/mysite

for*_*all 255

os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))
Run Code Online (Sandbox Code Playgroud)

至于模板文件夹的位置,我不知道,因为Django 1.4刚出来,我还没看过它.你可能应该在SE上提出另一个问题来解决这个问题.

您也可以使用normpath清理路径,而不是abspath.但是,在这种情况下,Django期望绝对路径而不是相对路径.

对于跨平台兼容性,请使用os.pardir而不是'..'.

  • 使用`..`或其他东西是个坏主意吗?为什么这个答案得票少? (3认同)
  • 我不知道为什么它获得的票数越来越少,但这是我一直使用的。它甚至在 [`normpath`](http://docs.python.org/library/os.path.html#os.path.normpath) 的示例中定义。另外,它会正确遍历符号链接。 (2认同)
  • 使用 abspath 只会稍微清理一下。如果它不存在,路径名的实际字符串将是`/Users/hobbes3/Sites/mysite/mysite/../templates`,这很好,但只是有点混乱。它还确保遵守 Django 使用绝对路径的提示。如果您处于使用相对路径的不同情况,您应该使用 normpath 来简化您的路径。 (2认同)
  • [这个问题刚刚被问及关于迁移新版Django的文件夹结构](http://stackoverflow.com/questions/9857364/whats-is-the-best-way-to-migrate-folder-and-files-结构 - 从 - django1-3到dj),所以你可能应该考虑解决你的第二个问题. (2认同)

loc*_*jay 81

要获取文件的文件夹,只需使用:

os.path.dirname(path) 
Run Code Online (Sandbox Code Playgroud)

要获取文件夹,请os.path.dirname再次使用

os.path.dirname(os.path.dirname(path))
Run Code Online (Sandbox Code Playgroud)

您可能想要检查是否__file__是符号链接:

if os.path.islink(__file__): path = os.readlink (__file__)
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法上去`n`文件夹而不必调用`os.path.dirname``n`次? (15认同)
  • @OriolNieto 是的,从 Python 3.4+ 版本开始,您可以使用 ```pathlib.Path.parents[levels_up-1]```。更多解决办法见【这个问题】(/sf/ask/3886174561/) (13认同)

Ala*_*ars 16

你想要这个:

BASE_DIR = os.path.join( os.path.dirname( __file__ ), '..' )
Run Code Online (Sandbox Code Playgroud)


bir*_*aum 12

如果您使用的是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])  # "."
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是最干净的方法。 (7认同)

小智 12

如果您更喜欢单行获取父目录,我建议这样做:

import os
    
parent_dir = os.path.split(os.getcwd())[0]
Run Code Online (Sandbox Code Playgroud)

os.path.split()方法返回一个元组(head,tail),其中tail是最后一个斜杠之后的所有内容。所以第一个索引是绝对路径的父索引。


Lor*_*ner 9

就个人而言,我会选择功能方法

def get_parent_dir(directory):
    import os
    return os.path.dirname(directory)

current_dirs_parent = get_parent_dir(os.getcwd())
Run Code Online (Sandbox Code Playgroud)


小智 7

我认为最简单的方法就是重用dirname()所以你可以调用

os.path.dirname(os.path.dirname( __file__ ))
Run Code Online (Sandbox Code Playgroud)

如果您的文件位于/Users/hobbes3/Sites/mysite/templates/method.py

这将返回"/ Users/hobbes3/Sites/mysite"


Ant*_*ins 6

from os.path import dirname, realpath, join
join(dirname(realpath(dirname(__file__))), 'templates')
Run Code Online (Sandbox Code Playgroud)

更新:

如果您碰巧settings.py通过符号链接"复制" ,@ forivall的答案更好:

~user/
    project1/  
        mysite/
            settings.py
        templates/
            wrong.html

    project2/
        mysite/
            settings.py -> ~user/project1/settings.py
        templates/
            right.html
Run Code Online (Sandbox Code Playgroud)

上面的方法将"看到",wrong.html而@ forivall的方法将会看到right.html

在没有符号链接的情况下,两个答案是相同的.


小智 6

这对于您想要启动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   
Run Code Online (Sandbox Code Playgroud)


Jul*_*laz 6

从工作目录上一级

import os
os.path.dirname(os.getcwd())
Run Code Online (Sandbox Code Playgroud)

或从当前目录

import os
os.path.dirname('current path')
Run Code Online (Sandbox Code Playgroud)