使用Python的os.path,如何进入一个目录?


224

我最近将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. 我应该保持template(其具有跨应用程序模板,如文件夹adminregistration在项目等)/User/hobbes3/Sites/mysite水平或在/User/hobbes3/Sites/mysite/mysite

不能你只需要使用oscd../mysite?或您想要的任何命令
Prelic

@prelic嗯?我不明白 我试图避免对路径进行硬编码,因为我settings.py在多个服务器中使用了相同的路径。唯一的区别可能是数据库凭据。我正在阅读os.path文档,但是找不到让您进入一个目录的命令。像cd ..
hobbes3 2012年

2
@ hobbes3你可以os.path.join( os.path.dirname( __file__ ), '..' ) ..上面的目录整个文件系统,当传递给不只是cd
Michael Berkowski 2012年

3
@Michael,最好使用os.path.join( os.path.dirname ( __file__), os.path.pardir)
mgilson 2012年

Answers:


285
os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))

至于template文件夹应该放哪里,我不知道自从Django 1.4刚问世以来,我还没有看过它。您可能应该在SE上问另一个问题以解决该问题。

您也可以使用normpath来清理路径,而不是abspath。但是,在这种情况下,Django需要绝对路径而不是相对路径。

为了实现跨平台兼容性,请使用os.pardir代替'..'


4
使用是个坏主意..吗?为什么这个答案得票少?
hobbes3 2012年

1
我不知道为什么它获得的选票减少,但这是我一直使用的选票。在示例中甚至定义了normpath。另外,它将正确遍历符号链接。
forivall 2012年

1
使用abspath只会清理一点。如果不存在,则路径名的实际字符串将为/Users/hobbes3/Sites/mysite/mysite/../templates,这很好,但会更加混乱。它还确保遵守Django关于使用绝对路径的提示。如果您在使用相对路径的其他情况下,则应使用normpath简化路径。
forivall 2012年

2
刚问这个问题有关新版本Django的迁移文件夹结构的问题,因此您可能应该使用它来解决第二个问题。
forivall 2012年

1
@Zitrax您是否知道任何平台会有所不同,还是只是为了将来的安全?(我实际上并不了解os.pardir,也从未真正了解os文档的底部)
forivall

98

要获取文件的文件夹,请使用:

os.path.dirname(path) 

要建立文件夹,只需os.path.dirname再次使用

os.path.dirname(os.path.dirname(path))

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

if os.path.islink(__file__): path = os.readlink (__file__)

17
有没有一种方法可以在n没有通话os.path.dirname n时间的情况下上传文件夹?
Oriol Nieto

9
@OriolNieto是的,从Python 3.4+开始,您可以使用pathlib.Path.parents[levels_up-1]。有关更多解决方案,请参阅此问题
jwalton

23

如果您使用的是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])  # "."

2
这绝对是最干净的方法。
hobbes3


9

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

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

current_dirs_parent = get_parent_dir(os.getcwd())

请注意,如果输入包含尾部斜杠(例如,os.path.dirname('/tmp/lala/')仍返回),则此答案不起作用'/tmp/lala'
Fruit Fruit

尾部的斜杠可以参考以下答案:stackoverflow.com/a/25669963/1074998
水果

7

我认为最简单的方法就是重用dirname(),因此您可以调用

os.path.dirname(os.path.dirname( __file__ ))

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

这将返回“ / Users / hobbes3 / Sites / mysite”


6
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

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


这种方法有什么问题吗?它的工作原理不错,看起来不错,但有点
破旧

它与链接的处理方式与接受的答案稍有不同。否则它们是相同的。
2013年

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   

可以使用for _ in xrange(depth)而不是跟踪局部变量。
Zitrax

2

对于像我这样的偏执狂,我更喜欢这个

TEMPLATE_DIRS = (
    __file__.rsplit('/', 2)[0] + '/templates',
)

8
也许不是'/'您应该使用os.sep
djhaskin987 2015年

1

打开n文件夹...运行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


0

通过使用,os.path我们可以像这样建立一个目录

one_directory_up_path = os.path.dirname('.')

在找到您想要的目录之后,您还可以与其他文件/目录路径一起加入

other_image_path = os.path.join(one_directory_up_path, 'other.jpg')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.