标签归档:path

我的Django安装在哪里?

问题:我的Django安装在哪里?

我使用Django,但需要查找默认模板和应用程序。

我不知道它的安装位置。

我怎么能找到那个?

I use Django but I need to find the default templates and applications.

I don’t know where it’s installed.

How can I find that?


回答 0

在CLI中,您可以执行以下操作:

>>> import django
>>> django
<module 'django' from '/usr/local/lib/python2.6/dist-packages/django/__init__.pyc'>

in the CLI you can do this:

>>> import django
>>> django
<module 'django' from '/usr/local/lib/python2.6/dist-packages/django/__init__.pyc'>

回答 1

$ python
>>> import django
>>> django.__file__
'/usr/local/lib/python2.7/site-packages/django/__init__.pyc'
$ python
>>> import django
>>> django.__file__
'/usr/local/lib/python2.7/site-packages/django/__init__.pyc'

回答 2

当前的最佳答案至少在Linux上不起作用。

从Django 教程中

如果您很难找到Django源文件在系统上的位置,请运行以下命令:

python -c "
import sys
sys.path = sys.path[1:]
import django
print(django.__path__)"

The current top answer doesn’t work, at least on linux.

From the Django tutorial:

If you have difficulty finding where the Django source files are located on your system, run the following command:

python -c "
import sys
sys.path = sys.path[1:]
import django
print(django.__path__)"

回答 3

在Microsft-Windows操作系统上:在python安装中的Lib / site-packages文件夹中。

On Microsft-Windows OS: In the Lib/site-packages folder inside your python installation.


回答 4

我正在描述的这种方法可跨操作系统使用…

您可以在命令行上尝试- python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

这将为您提供基本目录。在此处输入,/django/然后在其中找到所有默认模板,管理模板等。

希望这可以帮助…

This approach I am describing works across operating systems…

You try this on your command line – python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

This gives you the base directory. From there, type /django/ and here you find all the default templates, admin templates, etc.

Hope this helps…


回答 5

正如对@olafure的答案https://stackoverflow.com/a/12974642/4515198的评论所正确指出的那样,sys.path不需要分配。

以下内容就足够了:

python -c "import django; print(django.__path__)"

这里的-c选项用于告诉Python说“节目被传递作为字符串”(来源:命令$ python --helpbash

As the comments on @olafure’s answer https://stackoverflow.com/a/12974642/4515198 rightly say, the sys.path assignment is not required.

The following will be enough:

python -c "import django; print(django.__path__)"

Here the -c option is used to tell python that a “program is being passed in as string” (source: command $ python --help on bash)


回答 6

import django
django.__file__

输出将被赋予django文件夹的位置

'C:\\Users\\saigopi\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\django\\__init__.py'
import django
django.__file__

output will be given location of the django folder

'C:\\Users\\saigopi\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\django\\__init__.py'

回答 7

值得一提的是,如果您使用的是虚拟环境,则所有软件包都将位于项目的“ lib”下的根venv文件夹中。

Worth mentioning that if you are using a virtual env all the packages will be in your project’s root venv folder under “lib” …


回答 8

在终端上尝试一下。

$ python -v
import django # directory /home/user/.virtualenvs/myenv/local/lib/python2.7/site-packages/django
# some other imports.

Try this on an terminal.

$ python -v
import django # directory /home/user/.virtualenvs/myenv/local/lib/python2.7/site-packages/django
# some other imports.

回答 9

如果您使用的是virtualenv,则它将是:
/ home / user / path,安装django / django_directory / lib / python2.7 / site-packages / Django-1.8.1-py2.7.egg / django / contrib / admin的位置/templates/admin/base_site.html
base-site.html是默认模板。

If you are using virtualenv then it will be:
/home/user/path where you installed django/django_directory/lib/python2.7/site-packages/Django-1.8.1-py2.7.egg/django/contrib/admin/templates/admin/base_site.html
base-site.html is the default template.


如何找到Windows上Python的安装位置?

问题:如何找到Windows上Python的安装位置?

我想找出Windows上的Python安装路径。例如:

C:\Python25

如何找到Python的安装位置?

I want to find out my Python installation path on Windows. For example:

C:\Python25

How can I find where Python is installed?


回答 0

在您的Python解释器中,键入以下命令:

>>> import os
>>> import sys
>>> os.path.dirname(sys.executable)
'C:\\Python25'

In your Python interpreter, type the following commands:

>>> import os
>>> import sys
>>> os.path.dirname(sys.executable)
'C:\\Python25'

Also, you can club all these and use a single line command. Open cmd and enter following command

python -c "import os, sys; print(os.path.dirname(sys.executable))"

回答 1

如果您的环境变量中包含python,则可以在cmd中使用以下命令:

>>>其中python

或用于unix环境

>>>哪个python

命令行图片

If you have python in your enviroment variable then you can use the following command in cmd:

>>> where python

or for unix enviroment

>>> which python

command line image


回答 2

可能是

  • C:\ Python36
  • C:\ Users \(您登录的用户)\ AppData \ Local \ Programs \ Python \ Python36

It would be either of

  • C:\Python36
  • C:\Users\(Your logged in User)\AppData\Local\Programs\Python\Python36

回答 3

如果您需要了解Windows 的安装路径而不启动python解释器,请查看Windows注册表。

每个安装的Python版本在以下任一位置都有一个注册表项:

  • HKLM\SOFTWARE\Python\PythonCore\versionnumber\InstallPath
  • HKCU\SOFTWARE\Python\PythonCore\versionnumber\InstallPath

在64位Windows中,它将位于Wow6432Node密钥下:

  • HKLM\SOFTWARE\Wow6432Node\Python\PythonCore\versionnumber\InstallPath

If you need to know the installed path under Windows without starting the python interpreter, have a look in the Windows registry.

Each installed Python version will have a registry key in either:

  • HKLM\SOFTWARE\Python\PythonCore\versionnumber\InstallPath
  • HKCU\SOFTWARE\Python\PythonCore\versionnumber\InstallPath

In 64-bit Windows, it will be under the Wow6432Node key:

  • HKLM\SOFTWARE\Wow6432Node\Python\PythonCore\versionnumber\InstallPath

回答 4

在Windows安装上,我得到以下结果:

>>> import sys
>>> sys.executable
'C:\\Python26\\python.exe'
>>> sys.platform
'win32'
>>>

(您也可以寻找sys.path合理的位置。)

On my windows installation, I get these results:

>>> import sys
>>> sys.executable
'C:\\Python26\\python.exe'
>>> sys.platform
'win32'
>>>

(You can also look in sys.path for reasonable locations.)


回答 5

sys软件包中,您可以找到有关安装的许多有用信息:

import sys
print sys.executable
print sys.exec_prefix

我不确定这会在Windows系统上提供什么,但是在Mac上却executable指向Python二进制文件和exec_prefix安装根目录。

您也可以尝试使用以下方法检查sys模块:

import sys
for k,v in sys.__dict__.items():
    if not callable(v):
        print "%20s: %s" % (k,repr(v))

In the sys package, you can find a lot of useful information about your installation:

import sys
print sys.executable
print sys.exec_prefix

I’m not sure what this will give on your Windows system, but on my Mac executable points to the Python binary and exec_prefix to the installation root.

You could also try this for inspecting your sys module:

import sys
for k,v in sys.__dict__.items():
    if not callable(v):
        print "%20s: %s" % (k,repr(v))

回答 6

如果您想要安装成功后的路径,请先打开CMD并输入python或python -i

它将为您打开交互式外壳,然后键入

导入系统

可执行文件

点击Enter键,您将获得安装Python的路径…

If You want the Path After successful installation then first open you CMD and type python or python -i

It Will Open interactive shell for You and Then type

import sys

sys.executable

Hit enter and you will get path where your python is installed …


回答 7

简单的方法是

1) open CMD
2) type >>where python

Simple way is

1) open CMD
2) type >>where python

回答 8

您可以搜索“您帐户的环境变量”。如果您在路径中添加了Python,那么它将在您的环境变量帐户中显示为“路径”。

但几乎总是可以在“ C:\ Users \%User_name%\ AppData \ Local \ Programs \ Python \ Python_version ”中找到它

AppData ”文件夹可能已隐藏,从工具栏的“ 视图”部分可见。

You can search for the “environmental variable for you account”. If you have added the Python in the path, it’ll show as “path” in your environmental variable account.

but almost always you will find it in “C:\Users\%User_name%\AppData\Local\Programs\Python\Python_version

the ‘AppData‘ folder may be hidden, make it visible from the view section of toolbar.


回答 9

要知道Python的安装位置,可以where python在cmd.exe中执行。

To know where Python is installed you can execute where python in your cmd.exe.


回答 10

如果有人需要在C#中执行此操作,请使用以下代码:

static string GetPythonExecutablePath(int major = 3)
{
    var software = "SOFTWARE";
    var key = Registry.CurrentUser.OpenSubKey(software);
    if (key == null)
        key = Registry.LocalMachine.OpenSubKey(software);
    if (key == null)
        return null;

    var pythonCoreKey = key.OpenSubKey(@"Python\PythonCore");
    if (pythonCoreKey == null)
        pythonCoreKey = key.OpenSubKey(@"Wow6432Node\Python\PythonCore");
    if (pythonCoreKey == null)
        return null;

    var pythonVersionRegex = new Regex("^" + major + @"\.(\d+)-(\d+)$");
    var targetVersion = pythonCoreKey.GetSubKeyNames().
                                        Select(n => pythonVersionRegex.Match(n)).
                                        Where(m => m.Success).
                                        OrderByDescending(m => int.Parse(m.Groups[1].Value)).
                                        ThenByDescending(m => int.Parse(m.Groups[2].Value)).
                                        Select(m => m.Groups[0].Value).First();

    var installPathKey = pythonCoreKey.OpenSubKey(targetVersion + @"\InstallPath");
    if (installPathKey == null)
        return null;

    return (string)installPathKey.GetValue("ExecutablePath");
}

If anyone needs to do this in C# I’m using the following code:

static string GetPythonExecutablePath(int major = 3)
{
    var software = "SOFTWARE";
    var key = Registry.CurrentUser.OpenSubKey(software);
    if (key == null)
        key = Registry.LocalMachine.OpenSubKey(software);
    if (key == null)
        return null;

    var pythonCoreKey = key.OpenSubKey(@"Python\PythonCore");
    if (pythonCoreKey == null)
        pythonCoreKey = key.OpenSubKey(@"Wow6432Node\Python\PythonCore");
    if (pythonCoreKey == null)
        return null;

    var pythonVersionRegex = new Regex("^" + major + @"\.(\d+)-(\d+)$");
    var targetVersion = pythonCoreKey.GetSubKeyNames().
                                        Select(n => pythonVersionRegex.Match(n)).
                                        Where(m => m.Success).
                                        OrderByDescending(m => int.Parse(m.Groups[1].Value)).
                                        ThenByDescending(m => int.Parse(m.Groups[2].Value)).
                                        Select(m => m.Groups[0].Value).First();

    var installPathKey = pythonCoreKey.OpenSubKey(targetVersion + @"\InstallPath");
    if (installPathKey == null)
        return null;

    return (string)installPathKey.GetValue("ExecutablePath");
}

回答 11

如果不存在,请转到C:\ Users \ USER \ AppData \ Local \ Programs \ Python \ Python36,然后通过Windows + ^ R打开控制台,然后键入cmd并按Enter键键入python(如果安装在本地文件中)将显示其版本从那里输入以下import os import sys os.path.dirname(sys.executable)

Go to C:\Users\USER\AppData\Local\Programs\Python\Python36 if it is not there then open console by windows+^R Then type cmd and hit enter type python if installed in your local file it will show you its version from there type the following import os import sys os.path.dirname(sys.executable)


回答 12

如果您已经py安装了命令(可能已安装),则只需使用--list-paths命令的参数即可:

py --list-paths

输出示例:

py Launcher对于Windows
-3.8-32 C:\ Users \ cscott \ AppData \ Local \ Programs \ Python \ Python38-32 \ python.exe *
-2.7-64 C:\ Python27 \ python.exe 找到的已安装Python

*表示使用该py命令执行的脚本的当前活动版本。

If you have the py command installed, which you likely do, then just use the --list-paths argument to the command:

py --list-paths

Example output:

Installed Pythons found by py Launcher for Windows
-3.8-32 C:\Users\cscott\AppData\Local\Programs\Python\Python38-32\python.exe *
-2.7-64 C:\Python27\python.exe

The * indicates the currently active version for scripts executed using the py command.


回答 13

这对我有用: C:\Users\Your_user_name\AppData\Local\Programs\Python

我当前安装的python version3.7.0

希望这可以帮助!

This worked for me: C:\Users\Your_user_name\AppData\Local\Programs\Python

My currently installed python version is 3.7.0

Hope this helps!


回答 14

一般而言

‘C:\ Users \用户名\ AppData \ Local \ Programs \ Python \ Python-version’

或尝试使用(在cmd中)

哪里python

Its generally

‘C:\Users\user-name\AppData\Local\Programs\Python\Python-version’

or try using (in cmd )

where python


回答 15

如果您仍然卡住或得到这个

C:\\\Users\\\name of your\\\AppData\\\Local\\\Programs\\\Python\\\Python36

只需将2替换为1

C:\Users\akshay\AppData\Local\Programs\Python\Python36

if you still stuck or you get this

C:\\\Users\\\name of your\\\AppData\\\Local\\\Programs\\\Python\\\Python36

simply do this replace 2 \ with one

C:\Users\akshay\AppData\Local\Programs\Python\Python36

回答 16

我安装了2和3,发现3时遇到了相同的问题。幸运的是,在Windows路径中键入path可以让我找到安装它的位置。安装刚忘记的Python时,路径是一个选项。如果在安装Python 3时未选择设置路径,则可能无法使用-除非在安装时手动更新了路径。就我而言,它位于c:\ Program Files \ Python37 \ python.exe

I installed 2 and 3 and had the same problem finding 3. Fortunately, typing path at the windows path let me find where I had installed it. The path was an option when I installed Python which I just forgot. If you didn’t select setting the path when you installed Python 3 that probably won’t work – unless you manually updated the path when you installed it. In my case it was at c:\Program Files\Python37\python.exe


回答 17

如果anaconda navigator在Windows上使用,也可以enviornments在环境上滚动,该root环境将指示其安装位置。当您需要将此环境连接到要在其中集成一些python代码的其他应用程序时,可以使用该环境。

If you use anaconda navigator on windows, you can go too enviornments and scroll over the enviornments, the root enviorment will indicate where it is installed. It can help if you want to use this enviorment when you need to connect this to other applications, where you want to integrate some python code.


Python中的Windows路径

问题:Python中的Windows路径

例如,代表Windows目录的最佳方法是什么"C:\meshes\as"?我一直在尝试修改脚本,但是它永远无法正常工作,因为我似乎无法正确获得目录,我想是因为它'\'充当转义符?

What is the best way to represent a Windows directory, for example "C:\meshes\as"? I have been trying to modify a script but it never works because I can’t seem to get the directory right, I assume because of the '\' acting as escape character?


回答 0

您可以始终使用:

'C:/mydir'

这适用于linux和Windows。其他可能性是

'C:\\mydir'

如果您对某些名称有疑问,也可以尝试使用原始字符串文字:

r'C:\mydir'

但是,最佳实践是使用os.path始终为您的操作系统选择正确配置的模块功能:

os.path.join(mydir, myfile)

从python 3.4开始,您还可以使用pathlib模块。这等同于以上内容:

pathlib.Path(mydir, myfile)

要么

pathlib.Path(mydir) / myfile

you can use always:

'C:/mydir'

this works both in linux and windows. Other posibility is

'C:\\mydir'

if you have problems with some names you can also try raw string literals:

r'C:\mydir'

however best practice is to use the os.path module functions that always select the correct configuration for your OS:

os.path.join(mydir, myfile)

From python 3.4 you can also use the pathlib module. This is equivelent to the above:

pathlib.Path(mydir, myfile)

or

pathlib.Path(mydir) / myfile

回答 1

使用os.path模块。

os.path.join( "C:", "meshes", "as" )

或使用原始字符串

r"C:\meshes\as"

我也建议不要在路径或文件名中使用空格。您可以在字符串中使用双反斜杠。

"C:\\meshes\\as.jpg"

Use the os.path module.

os.path.join( "C:", "meshes", "as" )

Or use raw strings

r"C:\meshes\as"

I would also recommend no spaces in the path or file names. And you could use double backslashes in your strings.

"C:\\meshes\\as.jpg"

回答 2

是的,\在Python中,字符串文字表示转义序列的开始。在您的路径中,您有一个有效的两个字符的转义序列\a,该序列被折叠成一个字符,即ASCII Bell

>>> '\a'
'\x07'
>>> len('\a')
1
>>> 'C:\meshes\as'
'C:\\meshes\x07s'
>>> print('C:\meshes\as')
C:\meshess

其他常见的转义序列包括\t(制表符),\n(换行),\r(回车):

>>> list('C:\test')
['C', ':', '\t', 'e', 's', 't']
>>> list('C:\nest')
['C', ':', '\n', 'e', 's', 't']
>>> list('C:\rest')
['C', ':', '\r', 'e', 's', 't']

如您所见,在所有这些示例中,反斜杠和文字中的下一个字符被组合在一起以在最终字符串中形成单个字符。Python的转义序列的完整列表在这里

有多种解决方法:

  1. Python将不会处理与前缀字符串文字的转义序列rR

    >>> r'C:\meshes\as'
    'C:\\meshes\\as'
    >>> print(r'C:\meshes\as')
    C:\meshes\as
    
  2. Windows上的Python也应处理正斜杠。

  3. 您可以使用os.path.join

    >>> import os
    >>> os.path.join('C:', os.sep, 'meshes', 'as')
    'C:\\meshes\\as'
    
  4. …或较新的pathlib模块

    >>> from pathlib import Path
    >>> Path('C:', '/', 'meshes', 'as')
    WindowsPath('C:/meshes/as')
    

Yes, \ in Python string literals denotes the start of an escape sequence. In your path you have a valid two-character escape sequence \a, which is collapsed into one character that is ASCII Bell:

>>> '\a'
'\x07'
>>> len('\a')
1
>>> 'C:\meshes\as'
'C:\\meshes\x07s'
>>> print('C:\meshes\as')
C:\meshess

Other common escape sequences include \t (tab), \n (line feed), \r (carriage return):

>>> list('C:\test')
['C', ':', '\t', 'e', 's', 't']
>>> list('C:\nest')
['C', ':', '\n', 'e', 's', 't']
>>> list('C:\rest')
['C', ':', '\r', 'e', 's', 't']

As you can see, in all these examples the backslash and the next character in the literal were grouped together to form a single character in the final string. The full list of Python’s escape sequences is here.

There are a variety of ways to deal with that:

  1. Python will not process escape sequences in string literals prefixed with r or R:

    >>> r'C:\meshes\as'
    'C:\\meshes\\as'
    >>> print(r'C:\meshes\as')
    C:\meshes\as
    
  2. Python on Windows should handle forward slashes, too.

  3. You could use os.path.join

    >>> import os
    >>> os.path.join('C:', os.sep, 'meshes', 'as')
    'C:\\meshes\\as'
    
  4. … or the newer pathlib module

    >>> from pathlib import Path
    >>> Path('C:', '/', 'meshes', 'as')
    WindowsPath('C:/meshes/as')
    

回答 3

使用PowerShell

在Windows中,只要将PowerShell用作命令行界面,就可以/在所有地方像Linux或macOS一样在路径中使用。它预装在Windows上,并且支持许多Linux命令,例如lscommand。

如果使用Windows命令提示符(cmd在Windows“开始”菜单中键入时显示的命令提示符),则需要在其中指定路径\。您可以/在所有其他地方使用路径(代码编辑器,Python交互模式等)。

Use PowerShell

In Windows, you can use / in your path just like Linux or macOS in all places as long as you use PowerShell as your command-line interface. It comes pre-installed on Windows and it supports many Linux commands like ls command.

If you use Windows Command Prompt (the one that appears when you type cmd in Windows Start Menu), you need to specify paths with \ just inside it. You can use / paths in all other places (code editor, Python interactive mode, etc.).


回答 4

如果您想粘贴其他来源的Windows路径(例如,文件资源管理器),则可以通过input()python控制台中的调用来粘贴:

>>> input()
D:\EP\stuff\1111\this_is_a_long_path\you_dont_want\to_type\or_edit_by_hand
'D:\\EP\\stuff\\1111\\this_is_a_long_path\\you_dont_want\\to_type\\or_edit_by_hand'

然后复制结果

In case you’d like to paste windows path from other source (say, File Explorer) – you can do so via input() call in python console:

>>> input()
D:\EP\stuff\1111\this_is_a_long_path\you_dont_want\to_type\or_edit_by_hand
'D:\\EP\\stuff\\1111\\this_is_a_long_path\\you_dont_want\\to_type\\or_edit_by_hand'

Then just copy the result


如何使用Python以跨平台方式检查路径是绝对路径还是相对路径?

问题:如何使用Python以跨平台方式检查路径是绝对路径还是相对路径?

UNIX绝对路径以“ /”开头,而Windows则以字母“ C:”或“ \”开头。python是否具有标准功能来检查路径是绝对路径还是相对路径?

UNIX absolute path starts with ‘/’, whereas Windows starts with alphabet ‘C:’ or ‘\’. Does python has a standard function to check if a path is absolute or relative?


回答 0

os.path.isabsTrue如果路径是绝对的,False则返回,否则返回。该文档说它可以在Windows中运行(我可以确认它可以在Linux中正常运行)。

os.path.isabs(my_path)

os.path.isabs returns True if the path is absolute, False if not. The documentation says it works in windows (I can confirm it works in Linux personally).

os.path.isabs(my_path)

回答 1

如果您真正想要的是绝对路径,则不必费心检查它是否是绝对路径,只需获取abspath

import os

print os.path.abspath('.')

And if what you really want is the absolute path, don’t bother checking to see if it is, just get the abspath:

import os

print os.path.abspath('.')

回答 2

使用os.path.isabs


回答 3

import os.path

os.path.isabs('/home/user')
True

os.path.isabs('user')
False
import os.path

os.path.isabs('/home/user')
True

os.path.isabs('user')
False

回答 4

实际上,我认为以上答案均未解决真正的问题:跨平台路径。os.path的作用是加载OS依赖的’path’库版本。因此解决方案是显式加载相关的(OS)路径库:

import ntpath
import posixpath

ntpath.isabs("Z:/a/b/c../../H/I/J.txt")
    True
posixpath.isabs("Z:/a/b/c../../H/I/J.txt")
    False

Actually I think none of the above answers addressed the real issue: cross-platform paths. What os.path does is load the OS dependent version of ‘path’ library. so the solution is to explicitly load the relevant (OS) path library:

import ntpath
import posixpath

ntpath.isabs("Z:/a/b/c../../H/I/J.txt")
    True
posixpath.isabs("Z:/a/b/c../../H/I/J.txt")
    False

回答 5

python 3.4 pathlib可用。

In [1]: from pathlib import Path

In [2]: Path('..').is_absolute()
Out[2]: False

In [3]: Path('C:/').is_absolute()
Out[3]: True

In [4]: Path('..').resolve()
Out[4]: WindowsPath('C:/the/complete/path')

In [5]: Path('C:/').resolve()
Out[5]: WindowsPath('C:/')

From python 3.4 pathlib is available.

In [1]: from pathlib import Path

In [2]: Path('..').is_absolute()
Out[2]: False

In [3]: Path('C:/').is_absolute()
Out[3]: True

In [4]: Path('..').resolve()
Out[4]: WindowsPath('C:/the/complete/path')

In [5]: Path('C:/').resolve()
Out[5]: WindowsPath('C:/')

回答 6

换句话说,如果您不在当前工作目录中,那有点脏,但是对我有用。

import re
path = 'my/relative/path'
# path = '..my/relative/path'
# path = './my/relative/path'

pattern = r'([a-zA-Z0-9]|[.])+/'
is_ralative = bool(pattern)

another way if you are not in current working directory, kinda dirty but it works for me.

import re
path = 'my/relative/path'
# path = '..my/relative/path'
# path = './my/relative/path'

pattern = r'([a-zA-Z0-9]|[.])+/'
is_ralative = bool(pattern)

如何在Python中获取当前执行文件的路径?

问题:如何在Python中获取当前执行文件的路径?

这似乎是一个新手问题,但事实并非如此。一些通用方法并非在所有情况下都有效:

sys.argv [0]

这意味着使用path = os.path.abspath(os.path.dirname(sys.argv[0])),但是如果您是从另一个目录中的另一个Python脚本运行的,则此方法不起作用,并且这可能在现实生活中发生。

__文件__

这意味着使用path = os.path.abspath(os.path.dirname(__file__)),但是我发现这不起作用:

  • py2exe没有__file__属性,但是有一种解决方法
  • 当您从IDLE运行时,execute()没有__file__属性
  • 我得到的OS X 10.6 NameError: global name '__file__' is not defined

答案不完整的相关问题:

我正在寻找一种通用解决方案,该解决方案可以在所有上述用例中使用。

更新资料

这是一个测试用例的结果:

python a.py的输出(在Windows上)

a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz

py

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

subdir / b.py

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

C:.
|   a.py
\---subdir
        b.py

This may seem like a newbie question, but it is not. Some common approaches don’t work in all cases:

sys.argv[0]

This means using path = os.path.abspath(os.path.dirname(sys.argv[0])), but this does not work if you are running from another Python script in another directory, and this can happen in real life.

__file__

This means using path = os.path.abspath(os.path.dirname(__file__)), but I found that this doesn’t work:

  • py2exe doesn’t have a __file__ attribute, but there is a workaround
  • When you run from IDLE with execute() there is no __file__ attribute
  • OS X 10.6 where I get NameError: global name '__file__' is not defined

Related questions with incomplete answers:

I’m looking for a generic solution, one that would work in all above use cases.

Update

Here is the result of a testcase:

Output of python a.py (on Windows)

a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz

a.py

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

subdir/b.py

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

tree

C:.
|   a.py
\---subdir
        b.py

回答 0

您无法直接确定正在执行的主脚本的位置。毕竟,有时脚本根本不是来自文件。例如,它可能来自交互式解释器或仅存储在内存中的动态生成的代码。

但是,由于总是从文件加载模块,因此您可以可靠地确定模块的位置。如果使用以下代码创建模块并将其与主脚本放在同一目录中,则主脚本可以导入模块并使用该模块定位自身。

some_path / module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path / main.py:

import module_locator
my_path = module_locator.module_path()

如果您在不同目录中有多个主脚本,则可能需要一个以上的module_locator副本。

当然,如果您的主脚本是由其他工具加载的,而这些工具却不允许您导入与脚本位于同一位置的模块,那么您很不走运。在这种情况下,您所需要的信息根本就不在程序中任何地方。最好的选择是向工具作者提交错误。

You can’t directly determine the location of the main script being executed. After all, sometimes the script didn’t come from a file at all. For example, it could come from the interactive interpreter or dynamically generated code stored only in memory.

However, you can reliably determine the location of a module, since modules are always loaded from a file. If you create a module with the following code and put it in the same directory as your main script, then the main script can import the module and use that to locate itself.

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

If you have several main scripts in different directories, you may need more than one copy of module_locator.

Of course, if your main script is loaded by some other tool that doesn’t let you import modules that are co-located with your script, then you’re out of luck. In cases like that, the information you’re after simply doesn’t exist anywhere in your program. Your best bet would be to file a bug with the authors of the tool.


回答 1

首先,您需要从inspect和导入os

from inspect import getsourcefile
from os.path import abspath

接下来,只要您要在哪里使用它就可以找到源文件

abspath(getsourcefile(lambda:0))

First, you need to import from inspect and os

from inspect import getsourcefile
from os.path import abspath

Next, wherever you want to find the source file from you just use

abspath(getsourcefile(lambda:0))

回答 2

该解决方案即使在可执行文件中也很强大

import inspect, os.path

filename = inspect.getframeinfo(inspect.currentframe()).filename
path     = os.path.dirname(os.path.abspath(filename))

this solution is robust even in executables

import inspect, os.path

filename = inspect.getframeinfo(inspect.currentframe()).filename
path     = os.path.dirname(os.path.abspath(filename))

回答 3

我遇到了类似的问题,我认为这可能可以解决问题:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

它适用于常规脚本并处于空闲状态。我只能说是为他人尝试!

我的典型用法:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

现在,我使用__modpath__而不是__file__。

I was running into a similar problem, and I think this might solve the problem:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

It works for regular scripts and in idle. All I can say is try it out for others!

My typical usage:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

Now I use __modpath__ instead of __file__.


回答 4

简短的答案是,无法保证获得所需信息的方法,但是在实践中,启发式方法几乎总是起作用。您可能会看看如何在C中找到可执行文件的位置?。它从C的角度讨论了该问题,但是提出的解决方案很容易被转录为Python。

The short answer is that there is no guaranteed way to get the information you want, however there are heuristics that work almost always in practice. You might look at How do I find the location of the executable in C?. It discusses the problem from a C point of view, but the proposed solutions are easily transcribed into Python.


回答 5

请参阅我对从父文件夹导入模块问题的回答,以获取相关信息,包括为什么我的答案不使用不可靠的__file__变量。这个简单的解决方案应与作为模块的不同操作系统交叉兼容,osinspect作为Python的一部分。

首先,您需要导入inspectos模块的一部分。

from inspect import getsourcefile
from os.path import abspath

接下来,在Python代码中其他需要的地方使用以下行:

abspath(getsourcefile(lambda:0))

这个怎么运作:

从内置模块os(如下所述)abspath中导入工具。

Mac,NT或Posix的OS例程,取决于我们所使用的系统。

然后getsourcefile(从下面的描述)从内置模块导入inspect

从实时Python对象获取有用的信息。

  • abspath(path) 返回文件路径的绝对/完整版本
  • getsourcefile(lambda:0)以某种方式获取lambda函数对象的内部源文件,因此'<pyshell#nn>'在Python shell中返回或返回当前正在执行的Python代码的文件路径。

使用abspath的结果getsourcefile(lambda:0)应确保生成的文件路径是Python文件的完整文件路径。
这个解释好的解决方案最初是基于我如何在Python中获取当前执行文件路径的答案中的代码的?

See my answer to the question Importing modules from parent folder for related information, including why my answer doesn’t use the unreliable __file__ variable. This simple solution should be cross-compatible with different operating systems as the modules os and inspect come as part of Python.

First, you need to import parts of the inspect and os modules.

from inspect import getsourcefile
from os.path import abspath

Next, use the following line anywhere else it’s needed in your Python code:

abspath(getsourcefile(lambda:0))

How it works:

From the built-in module os (description below), the abspath tool is imported.

OS routines for Mac, NT, or Posix depending on what system we’re on.

Then getsourcefile (description below) is imported from the built-in module inspect.

Get useful information from live Python objects.

  • abspath(path) returns the absolute/full version of a file path
  • getsourcefile(lambda:0) somehow gets the internal source file of the lambda function object, so returns '<pyshell#nn>' in the Python shell or returns the file path of the Python code currently being executed.

Using abspath on the result of getsourcefile(lambda:0) should make sure that the file path generated is the full file path of the Python file.
This explained solution was originally based on code from the answer at How do I get the path of the current executed file in Python?.


回答 6

您只是简单地打电话给:

path = os.path.abspath(os.path.dirname(sys.argv[0]))

代替:

path = os.path.dirname(os.path.abspath(sys.argv[0]))

abspath()为您提供sys.argv[0](代码所在的文件名)的绝对路径,并dirname()返回不包含文件名的目录路径。

You have simply called:

path = os.path.abspath(os.path.dirname(sys.argv[0]))

instead of:

path = os.path.dirname(os.path.abspath(sys.argv[0]))

abspath() gives you the absolute path of sys.argv[0] (the filename your code is in) and dirname() returns the directory path without the filename.


回答 7

这应该以跨平台的方式来解决问题(只要您不使用解释器之类):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys.path[0]是您的调用脚本所在的目录(它首先查找该脚本要使用的模块)。我们可以将文件本身的名称从结尾删除sys.argv[0](这是我所做的os.path.basename)。os.path.join只是以跨平台的方式将它们粘在一起。os.path.realpath只要确保我们得到的符号链接名称与脚本本身的名称不同,就仍能获得脚本的真实名称。

我没有Mac;因此,我尚未对此进行测试。请让我知道它是否有效,好像应该起作用。我在Linux(Xubuntu)和Python 3.4上对此进行了测试。请注意,许多解决此问题的方法在Mac上不起作用(因为我听说__file__Mac上不存在此解决方案)。

请注意,如果脚本是符号链接,它将为您提供链接到的文件的路径(而不是符号链接的路径)。

This should do the trick in a cross-platform way (so long as you’re not using the interpreter or something):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys.path[0] is the directory that your calling script is in (the first place it looks for modules to be used by that script). We can take the name of the file itself off the end of sys.argv[0] (which is what I did with os.path.basename). os.path.join just sticks them together in a cross-platform way. os.path.realpath just makes sure if we get any symbolic links with different names than the script itself that we still get the real name of the script.

I don’t have a Mac; so, I haven’t tested this on one. Please let me know if it works, as it seems it should. I tested this in Linux (Xubuntu) with Python 3.4. Note that many solutions for this problem don’t work on Macs (since I’ve heard that __file__ is not present on Macs).

Note that if your script is a symbolic link, it will give you the path of the file it links to (and not the path of the symbolic link).


回答 8

您可以Pathpathlib模块中使用:

from pathlib import Path

# ...

Path(__file__)

您可以使用call进行parent进一步操作:

Path(__file__).parent

You can use Path from the pathlib module:

from pathlib import Path

# ...

Path(__file__)

You can use call to parent to go further in the path:

Path(__file__).parent

回答 9

如果代码来自文件,则可以获取其全名

sys._getframe().f_code.co_filename

您也可以将函数名称检索为 f_code.co_name

If the code is coming from a file, you can get its full name

sys._getframe().f_code.co_filename

You can also retrieve the function name as f_code.co_name


回答 10

只需添加以下内容:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

要么:

from sys import *
print(sys.argv[0])

Simply add the following:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

Or:

from sys import *
print(sys.argv[0])

回答 11

我的解决方案是:

import os
print(os.path.dirname(os.path.abspath(__file__)))

My solution is:

import os
print(os.path.dirname(os.path.abspath(__file__)))

回答 12

import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))
import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))

使用代码存储库时如何引用资源的相对路径

问题:使用代码存储库时如何引用资源的相对路径

我们正在使用一个代码存储库,该代码存储库同时部署到Windows和Linux中-有时位于不同的目录中。项目内部的模块之一应如何引用项目中的非Python资源之一(CSV文件等)?

如果我们做类似的事情:

thefile=open('test.csv')

要么:

thefile=open('../somedirectory/test.csv')

仅当脚本从一个特定目录或目录的子集运行时,它才起作用。

我想做的是这样的:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

可能吗?

We are working with a code repository which is deployed to both Windows and Linux – sometimes in different directories. How should one of the modules inside the project refer to one of the non-Python resources in the project (CSV files, etc.)?

If we do something like:

thefile=open('test.csv')

or:

thefile=open('../somedirectory/test.csv')

It will work only when the script is run from one specific directory, or a subset of the directories.

What I would like to do is something like:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

Is it possible?


回答 0

尝试使用相对于当前文件路径的文件名。“ ./my_file”的示例:

fn = os.path.join(os.path.dirname(__file__), 'my_file')

在Python 3.4+中,您还可以使用pathlib

fn = pathlib.Path(__file__).parent / 'my_file'

Try to use a filename relative to the current files path. Example for ‘./my_file’:

fn = os.path.join(os.path.dirname(__file__), 'my_file')

In Python 3.4+ you can also use pathlib:

fn = pathlib.Path(__file__).parent / 'my_file'

回答 1

如果您使用安装工具或分发(setup.py安装),则访问这些打包资源的“正确”方法似乎是使用package_resources。

以您的情况为例

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

当然,哪个读取资源,读取的二进制数据将是my_data的值

如果只需要文件名,也可以使用

resource_filename(package_or_requirement, resource_name)

例:

resource_filename("MyPackage","foo.dat")

优点是,即使是像鸡蛋一样的存档发行版,它也可以保证正常工作。

请参阅http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api

If you are using setup tools or distribute (a setup.py install) then the “right” way to access these packaged resources seem to be using package_resources.

In your case the example would be

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

Which of course reads the resource and the read binary data would be the value of my_data

If you just need the filename you could also use

resource_filename(package_or_requirement, resource_name)

Example:

resource_filename("MyPackage","foo.dat")

The advantage is that its guaranteed to work even if it is an archive distribution like an egg.

See http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api


回答 2

在Python中,路径是相对于当前工作目录的,在大多数情况下,该目录是您运行程序的目录。在当前的工作目录很可能不是同你的模块文件的目录,所以使用相对路径至当前的模块文件始终是一个不错的选择。

使用绝对路径应该是最好的解决方案:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')

In Python, paths are relative to the current working directory, which in most cases is the directory from which you run your program. The current working directory is very likely not as same as the directory of your module file, so using a path relative to your current module file is always a bad choice.

Using absolute path should be the best solution:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')

回答 3

我经常使用与此类似的东西:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

变量

__file__

保存您在其中编写该代码的脚本的文件名,因此您可以创建相对于脚本的路径,但仍使用绝对路径编写。它运行良好的原因有几个:

  • 路径是绝对的,但仍然是相对的
  • 该项目仍可以部署在相对的容器中

但是您需要注意平台兼容性-Windows的os.pathsep与UNIX不同。

I often use something similar to this:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

The variable

__file__

holds the file name of the script you write that code in, so you can make paths relative to script, but still written with absolute paths. It works quite well for several reasons:

  • path is absolute, but still relative
  • the project can still be deployed in a relative container

But you need to watch for platform compatibility – Windows’ os.pathsep is different than UNIX.


回答 4

import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

您还可以尝试规范化cwd使用os.path.abspath(os.getcwd())。更多信息在这里

import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

You also try to normalize your cwd using os.path.abspath(os.getcwd()). More info here.


回答 5

您可以使用内置__file__变量。它包含当前文件的路径。我将在您项目的根目录下的模块中实现getBaseOfProject。在那里,我将获得路径的一部分__file__并将其返回。然后,可以在项目的任何地方使用此方法。

You can use the build in __file__ variable. It contains the path of the current file. I would implement getBaseOfProject in a module in the root of your project. There I would get the path part of __file__ and would return that. This method can then be used everywhere in your project.


回答 6

我在这里有点难过 想要将一些资源文件打包到wheel文件中并访问它们。打包过程是否使用清单文件,但是pip install不会安装它,除非它是子目录。希望这些精彩的镜头会有所帮助

├── cnn_client
   ├── image_preprocessor.py
   ├── __init__.py
   ├── resources
      ├── mscoco_complete_label_map.pbtxt
      ├── retinanet_complete_label_map.pbtxt
      └── retinanet_label_map.py
   ├── tf_client.py

清单

recursive-include cnn_client/resources *

使用标准setup.py创建了一个weel。pip安装了wheel文件。安装后检查是否已安装资源。他们是

ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt 
 retinanet_label_map.py  

在tfclient.py中访问这些文件。

templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
 file_path = os.path.join(templates_dir, \
            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()

而且有效。

I got stumped here a bit. Wanted to package some resource files into a wheel file and access them. Did the packaging using manifest file, but pip install was not installing it unless it was a sub directory. Hoping these sceen shots will help

├── cnn_client
│   ├── image_preprocessor.py
│   ├── __init__.py
│   ├── resources
│   │   ├── mscoco_complete_label_map.pbtxt
│   │   ├── retinanet_complete_label_map.pbtxt
│   │   └── retinanet_label_map.py
│   ├── tf_client.py

MANIFEST.in

recursive-include cnn_client/resources *

Created a weel using standard setup.py . pip installed the wheel file. After installation checked if resources are installed. They are

ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt 
 retinanet_label_map.py  

In tfclient.py to access these files. from

templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
 file_path = os.path.join(templates_dir, \
            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()

And it works.


回答 7

我花了很长时间弄清楚这个问题的答案,但是我终于明白了(实际上很简单):

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

这会将子文件夹的相对路径附加到python的目录中,这看起来既快速又肮脏,但它的工作原理很像:)

I spent a long time figuring out the answer to this, but I finally got it (and it’s actually really simple):

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

This will append the relative path of your subfolder to the directories for python to look in It’s pretty quick and dirty, but it works like a charm :)


如何在Python中列出目录的内容?

问题:如何在Python中列出目录的内容?

不能很难,但是我有一个精神障碍。

Can’t be hard, but I’m having a mental block.


回答 0

import os
os.listdir("path") # returns list
import os
os.listdir("path") # returns list

回答 1

单程:

import os
os.listdir("/home/username/www/")

另一种方式

glob.glob("/home/username/www/*")

在这里找到示例

glob.glob上面的方法不会列出隐藏文件。

自从几年前我最初回答这个问题以来,pathlib已添加到Python。我现在列出目录的首选方法通常涉及对象的iterdir方法Path

from pathlib import Path
print(*Path("/home/username/www/").iterdir(), sep="\n")

One way:

import os
os.listdir("/home/username/www/")

Another way:

glob.glob("/home/username/www/*")

Examples found here.

The glob.glob method above will not list hidden files.

Since I originally answered this question years ago, pathlib has been added to Python. My preferred way to list a directory now usually involves the iterdir method on Path objects:

from pathlib import Path
print(*Path("/home/username/www/").iterdir(), sep="\n")

回答 2

os.walk 如果需要递归可以使用:

import os
start_path = '.' # current directory
for path,dirs,files in os.walk(start_path):
    for filename in files:
        print os.path.join(path,filename)

os.walk can be used if you need recursion:

import os
start_path = '.' # current directory
for path,dirs,files in os.walk(start_path):
    for filename in files:
        print os.path.join(path,filename)

回答 3

glob.globos.listdir将会做到。

glob.glob or os.listdir will do it.


回答 4

os模块处理所有这些东西。

os.listdir(path)

返回一个列表,其中包含由path给出的目录中条目的名称。该列表是任意顺序的。它不包括特殊条目“。” 和“ ..”,即使它们存在于目录中。

可用性:Unix,Windows。

The os module handles all that stuff.

os.listdir(path)

Return a list containing the names of the entries in the directory given by path. The list is in arbitrary order. It does not include the special entries ‘.’ and ‘..’ even if they are present in the directory.

Availability: Unix, Windows.


回答 5

在Python 3.4+中,您可以使用新pathlib软件包:

from pathlib import Path
for path in Path('.').iterdir():
    print(path)

Path.iterdir()返回一个迭代器,可以很容易地将其变成list

contents = list(Path('.').iterdir())

In Python 3.4+, you can use the new pathlib package:

from pathlib import Path
for path in Path('.').iterdir():
    print(path)

Path.iterdir() returns an iterator, which can be easily turned into a list:

contents = list(Path('.').iterdir())

回答 6

从Python 3.5开始,您可以使用os.scandir

区别在于它返回文件条目而不是名称。在某些操作系统(例如Windows)上,这意味着您不必os.path.isdir/file知道它是否是文件,并且可以节省CPU时间,因为stat在Windows中扫描目录时已完成此操作:

列出目录并打印大于max_value字节的文件的示例:

for dentry in os.scandir("/path/to/dir"):
    if dentry.stat().st_size > max_value:
       print("{} is biiiig".format(dentry.name))

在此处阅读基于性能的详尽答案)

Since Python 3.5, you can use os.scandir.

The difference is that it returns file entries not names. On some OSes like windows, it means that you don’t have to os.path.isdir/file to know if it’s a file or not, and that saves CPU time because stat is already done when scanning dir in Windows:

example to list a directory and print files bigger than max_value bytes:

for dentry in os.scandir("/path/to/dir"):
    if dentry.stat().st_size > max_value:
       print("{} is biiiig".format(dentry.name))

(read an extensive performance-based answer of mine here)


回答 7

下面的代码将列出目录和目录中的文件。另一个是os.walk

def print_directory_contents(sPath):
        import os                                       
        for sChild in os.listdir(sPath):                
            sChildPath = os.path.join(sPath,sChild)
            if os.path.isdir(sChildPath):
                print_directory_contents(sChildPath)
            else:
                print(sChildPath)

Below code will list directories and the files within the dir. The other one is os.walk

def print_directory_contents(sPath):
        import os                                       
        for sChild in os.listdir(sPath):                
            sChildPath = os.path.join(sPath,sChild)
            if os.path.isdir(sChildPath):
                print_directory_contents(sChildPath)
            else:
                print(sChildPath)

Python中的相对路径

问题:Python中的相对路径

我正在构建一个简单的工作助手脚本,该脚本会将我们代码库中的几个模板文件复制到当前目录。但是,我没有存储模板的目录的绝对路径。我确实有一个来自脚本的相对路径,但是当我调用该脚本时,会将其视为相对于当前工作目录的路径。有没有一种方法可以指定此相对URL来自脚本的位置?

I’m building a simple helper script for work that will copy a couple of template files in our code base to the current directory. I don’t, however, have the absolute path to the directory where the templates are stored. I do have a relative path from the script but when I call the script it treats that as a path relative to the current working directory. Is there a way to specify that this relative url is from the location of the script instead?


回答 0

在具有脚本的文件中,您想要执行以下操作:

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

这将为您提供要查找的文件的绝对路径。请注意,如果您使用的是setuptools,则应该改用其包资源API

更新:我在这里回应评论,所以我可以粘贴代码示例。:-)

我是否认为__file__并非总是可用(例如,当您直接运行文件而不是导入文件时)是否正确?

__main__当您提到直接运行文件时,我假设您的意思是脚本。如果是这样,在我的系统上似乎不是这种情况(在OS X 10.5.7上为python 2.5.1):

#foo.py
import os
print os.getcwd()
print __file__

#in the interactive interpreter
>>> import foo
/Users/jason
foo.py

#and finally, at the shell:
~ % python foo.py
/Users/jason
foo.py

但是,我确实知道__file__在C扩展上有一些怪癖。例如,我可以在Mac上执行此操作:

>>> import collections #note that collections is a C extension in Python 2.5
>>> collections.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-
dynload/collections.so'

但是,这在Windows计算机上引发了异常。

In the file that has the script, you want to do something like this:

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

This will give you the absolute path to the file you’re looking for. Note that if you’re using setuptools, you should probably use its package resources API instead.

UPDATE: I’m responding to a comment here so I can paste a code sample. :-)

Am I correct in thinking that __file__ is not always available (e.g. when you run the file directly rather than importing it)?

I’m assuming you mean the __main__ script when you mention running the file directly. If so, that doesn’t appear to be the case on my system (python 2.5.1 on OS X 10.5.7):

#foo.py
import os
print os.getcwd()
print __file__

#in the interactive interpreter
>>> import foo
/Users/jason
foo.py

#and finally, at the shell:
~ % python foo.py
/Users/jason
foo.py

However, I do know that there are some quirks with __file__ on C extensions. For example, I can do this on my Mac:

>>> import collections #note that collections is a C extension in Python 2.5
>>> collections.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-
dynload/collections.so'

However, this raises an exception on my Windows machine.


回答 1

您需要os.path.realpath(以下示例将父目录添加到您的路径)

import sys,os
sys.path.append(os.path.realpath('..'))

you need os.path.realpath (sample below adds the parent directory to your path)

import sys,os
sys.path.append(os.path.realpath('..'))

回答 2

如已接受的答案中所述

import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, '/relative/path/to/file/you/want')

我只想补充一点

后面的字符串不能以反斜杠开头,实际上任何字符串都不应包含反斜杠

应该是这样的

import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, 'relative','path','to','file','you','want')

在某些情况下,可接受的答案可能会误导您,请参阅链接以获取详细信息

As mentioned in the accepted answer

import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, '/relative/path/to/file/you/want')

I just want to add that

the latter string can’t begin with the backslash , infact no string should include a backslash

It should be something like

import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, 'relative','path','to','file','you','want')

The accepted answer can be misleading in some cases , please refer to this link for details


回答 3

现在是2018年,Python已经发展到__future__很久以前了。因此,如何使用神奇pathlib与Python 3.4来完成任务,而不是疲于应付osos.pathglobshutil,等。

因此,这里有3条路径(可能是重复的):

  • mod_path:这是简单帮助程序脚本的路径
  • src_path:包含几个等待复制的模板文件
  • cwd当前目录,这些模板文件的目标。

而问题是:我们没有的完整路径src_path,只知道它的相对路径mod_path

现在,让我们以惊人的方式解决这个问题pathlib

# Hope you don't be imprisoned by legacy Python code :)
from pathlib import Path

# `cwd`: current directory is straightforward
cwd = Path.cwd()

# `mod_path`: According to the accepted answer and combine with future power
# if we are in the `helper_script.py`
mod_path = Path(__file__).parent
# OR if we are `import helper_script`
mod_path = Path(helper_script.__file__).parent

# `src_path`: with the future power, it's just so straightforward
relative_path_1 = 'same/parent/with/helper/script/'
relative_path_2 = '../../or/any/level/up/'
src_path_1 = (mod_path / relative_path_1).resolve()
src_path_2 = (mod_path / relative_path_2).resolve()

将来,它就这么简单。:D


此外,我们可以选择并检查和复制/移动这些模板文件pathlib

if src_path != cwd:
    # When we have different types of files in the `src_path`
    for template_path in src_path.glob('*.ini'):
        fname = template_path.name
        target = cwd / fname
        if not target.exists():
            # This is the COPY action
            with target.open(mode='wb') as fd:
                fd.write(template_path.read_bytes())
            # If we want MOVE action, we could use:
            # template_path.replace(target)

It’s 2018 now, and Python have already evolve to the __future__ long time ago. So how about using the amazing pathlib coming with Python 3.4 to accomplish the task instead of struggling with os, os.path, glob, shutil, etc.

So we have 3 paths here (possibly duplicated):

  • mod_path: which is the path of the simple helper script
  • src_path: which contains a couple of template files waiting to be copied.
  • cwd: current directory, the destination of those template files.

and the problem is: we don’t have the full path of src_path, only know it’s relative path to the mod_path.

Now let’s solve this with the the amazing pathlib:

# Hope you don't be imprisoned by legacy Python code :)
from pathlib import Path

# `cwd`: current directory is straightforward
cwd = Path.cwd()

# `mod_path`: According to the accepted answer and combine with future power
# if we are in the `helper_script.py`
mod_path = Path(__file__).parent
# OR if we are `import helper_script`
mod_path = Path(helper_script.__file__).parent

# `src_path`: with the future power, it's just so straightforward
relative_path_1 = 'same/parent/with/helper/script/'
relative_path_2 = '../../or/any/level/up/'
src_path_1 = (mod_path / relative_path_1).resolve()
src_path_2 = (mod_path / relative_path_2).resolve()

In the future, it just that simple. :D


Moreover, we can select and check and copy/move those template files with pathlib:

if src_path != cwd:
    # When we have different types of files in the `src_path`
    for template_path in src_path.glob('*.ini'):
        fname = template_path.name
        target = cwd / fname
        if not target.exists():
            # This is the COPY action
            with target.open(mode='wb') as fd:
                fd.write(template_path.read_bytes())
            # If we want MOVE action, we could use:
            # template_path.replace(target)

回答 4

考虑我的代码:

import os


def readFile(filename):
    filehandle = open(filename)
    print filehandle.read()
    filehandle.close()



fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir

#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)

#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)

#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)

#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)

Consider my code:

import os


def readFile(filename):
    filehandle = open(filename)
    print filehandle.read()
    filehandle.close()



fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir

#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)

#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)

#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)

#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)

回答 5

请参见sys.path 。在程序启动时进行初始化,此列表的第一项path [0]是包含用于调用Python解释器的脚本的目录。

将此路径用作应用相对路径的根文件夹

>>> import sys
>>> import os.path
>>> sys.path[0]
'C:\\Python25\\Lib\\idlelib'
>>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6
>>> os.path.join(sys.path[0], "path_to_libs")
'C:\\Python25\\Lib\\idlelib\\path_to_libs'

See sys.path As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter.

Use this path as the root folder from which you apply your relative path

>>> import sys
>>> import os.path
>>> sys.path[0]
'C:\\Python25\\Lib\\idlelib'
>>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6
>>> os.path.join(sys.path[0], "path_to_libs")
'C:\\Python25\\Lib\\idlelib\\path_to_libs'

回答 6

而不是使用

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

如公认的答案中所示,使用起来会更可靠:

import inspect
import os
dirname = os.path.dirname(os.path.abspath(inspect.stack()[0][1]))
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

因为使用__file__将返回从中加载模块的文件(如果是从文件中加载的),那么如果从其他位置调用了带有脚本的文件,则返回的目录将不正确。

这些答案提供了更多详细信息:https : //stackoverflow.com/a/31867043/5542253https://stackoverflow.com/a/50502/5542253

Instead of using

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

as in the accepted answer, it would be more robust to use:

import inspect
import os
dirname = os.path.dirname(os.path.abspath(inspect.stack()[0][1]))
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

because using __file__ will return the file from which the module was loaded, if it was loaded from a file, so if the file with the script is called from elsewhere, the directory returned will not be correct.

These answers give more detail: https://stackoverflow.com/a/31867043/5542253 and https://stackoverflow.com/a/50502/5542253


回答 7

嗨,首先,您应该了解函数os.path.abspath(path)os.path.relpath(path)

总之os.path.abspath则(路径)使一个相对路径绝对路径。如果提供的路径本身是绝对路径,则该函数将返回相同的路径。

类似地 os.path.relpath(path)绝对路径设为相对路径。如果提供的路径本身是相对路径,则该函数将返回相同的路径。

下面的示例可以使您正确理解以上概念

假设我有一个文件input_file_list.txt,其中包含要由我的python脚本处理的输入文件的列表。

D:\ conc \ input1.dic

D:\ conc \ input2.dic

D:\ Copyioconc \ input_file_list.txt

如果您看到上述文件夹结构,则copyofconc文件夹中存在input_file_list.txt,而python脚本中要处理的文件则存在于 conc文件夹文件

但是文件input_file_list.txt的内容如下所示:

.. \ conc \ input1.dic

.. \ conc \ input2.dic

我的python脚本存在于D中:驱动器中。

并且input_file_list.txt文件中提供的相对路径相对于input_file_list.txt文件的路径。

因此,当python脚本执行当前工作目录时(使用os.getcwd()获取路径)

因为我的相对路径是相对于input_file_list.txt的,即“ D:\ Copyofconc”,所以我必须将当前工作目录更改为 “ D:\ Copyofconc”

因此,我必须使用os.chdir(’D:\ Copyofconc’),因此当前工作目录应为“ D:\ Copyofconc”

现在获取文件input1.dicinput2.dic,我将读取“ .. \ conc \ input1.dic”行,然后应使用以下命令

input1_path = os.path.abspath(’.. \ conc \ input1.dic’)(将相对路径更改为绝对路径。此处,由于当前工作目录为“ D:\ Copyofconc”,因此文件为“。\ conc \ input1”。 dic”应相对于“ D:\ Copyofconc”进行访问)

所以input1_path应该是“ D:\ conc \ input1.dic”

Hi first of all you should understand functions os.path.abspath(path) and os.path.relpath(path)

In short os.path.abspath(path) makes a relative path to absolute path. And if the path provided is itself a absolute path then the function returns the same path.

similarly os.path.relpath(path) makes a absolute path to relative path. And if the path provided is itself a relative path then the function returns the same path.

Below example can let you understand the above concept properly:

suppose i have a file input_file_list.txt which contains list of input files to be processed by my python script.

D:\conc\input1.dic

D:\conc\input2.dic

D:\Copyioconc\input_file_list.txt

If you see above folder structure, input_file_list.txt is present in Copyofconc folder and the files to be processed by the python script are present in conc folder

But the content of the file input_file_list.txt is as shown below:

..\conc\input1.dic

..\conc\input2.dic

And my python script is present in D: drive.

And the relative path provided in the input_file_list.txt file are relative to the path of input_file_list.txt file.

So when python script shall executed the current working directory (use os.getcwd() to get the path)

As my relative path is relative to input_file_list.txt, that is “D:\Copyofconc”, i have to change the current working directory to “D:\Copyofconc”.

So i have to use os.chdir(‘D:\Copyofconc’), so the current working directory shall be “D:\Copyofconc”.

Now to get the files input1.dic and input2.dic, i will read the lines “..\conc\input1.dic” then shall use the command

input1_path= os.path.abspath(‘..\conc\input1.dic’) (to change relative path to absolute path. Here as current working directory is “D:\Copyofconc”, the file “.\conc\input1.dic” shall be accessed relative to “D:\Copyofconc”)

so input1_path shall be “D:\conc\input1.dic”


回答 8

此代码将返回到主脚本的绝对路径。

import os
def whereAmI():
    return os.path.dirname(os.path.realpath(__import__("__main__").__file__))

即使在模块中也可以使用。

This code will return the absolute path to the main script.

import os
def whereAmI():
    return os.path.dirname(os.path.realpath(__import__("__main__").__file__))

This will work even in a module.


回答 9

一个对我有用的替代方法:

this_dir = os.path.dirname(__file__) 
filename = os.path.realpath("{0}/relative/file.path".format(this_dir))

An alternative which works for me:

this_dir = os.path.dirname(__file__) 
filename = os.path.realpath("{0}/relative/file.path".format(this_dir))

回答 10

对我有用的是使用sys.path.insert。然后,我指定了需要进入的目录。例如,我只需要上一个目录。

import sys
sys.path.insert(0, '../')

What worked for me is using sys.path.insert. Then I specified the directory I needed to go. For example I just needed to go up one directory.

import sys
sys.path.insert(0, '../')

回答 11

我不确定这是否适用于某些旧版本,但是我相信Python 3.3具有本机相对路径支持。

例如,以下代码应在与python脚本相同的文件夹中创建一个文本文件:

open("text_file_name.txt", "w+t")

(请注意,如果是相对路径,则开头不应有正斜杠或反斜杠)

I’m not sure if this applies to some of the older versions, but I believe Python 3.3 has native relative path support.

For example the following code should create a text file in the same folder as the python script:

open("text_file_name.txt", "w+t")

(note that there shouldn’t be a forward or backslash at the beginning if it’s a relative path)


为什么os.path.join()在这种情况下不起作用?

问题:为什么os.path.join()在这种情况下不起作用?

下面的代码将不会加入,调试后,该命令将不会存储整个路径,而只会存储最后一个条目。

os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')

当我对此进行测试时,它仅存储/new_sandbox/部分代码。

The below code will not join, when debugged the command does not store the whole path but just the last entry.

os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')

When I test this it only stores the /new_sandbox/ part of the code.


回答 0

后面的字符串不应以斜杠开头。如果它们以斜杠开头,那么它们将被视为“绝对路径”,并且丢弃它们之前的所有内容。

Python文档os.path.join引用

如果组件是绝对路径,则所有先前的组件都将被丢弃,并且连接将从绝对路径组件继续。

请注意,在Windows上,与驱动器号有关的行为与早期的Python版本相比似乎有所变化:

在Windows上,r'\foo'遇到绝对路径组件(例如)时,不会重置驱动器号。如果某个组件包含驱动器号,则会丢弃所有先前的组件,并重置驱动器号。请注意,由于每个驱动器都有一个当前目录,因此os.path.join("c:", "foo")表示相对于驱动器C:c:foo)上当前目录的路径,而不是c:\foo

The latter strings shouldn’t start with a slash. If they start with a slash, then they’re considered an “absolute path” and everything before them is discarded.

Quoting the Python docs for os.path.join:

If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.

Note on Windows, the behaviour in relation to drive letters, which seems to have changed compared to earlier Python versions:

On Windows, the drive letter is not reset when an absolute path component (e.g., r'\foo') is encountered. If a component contains a drive letter, all previous components are thrown away and the drive letter is reset. Note that since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.


回答 1

的想法os.path.join()是使您的程序跨平台(linux / windows / etc)。

即使是一个斜杠也会破坏它。

因此,仅当与某种参考点(例如os.environ['HOME']或)一起使用时,它才有意义 os.path.dirname(__file__)

The idea of os.path.join() is to make your program cross-platform (linux/windows/etc).

Even one slash ruins it.

So it only makes sense when being used with some kind of a reference point like os.environ['HOME'] or os.path.dirname(__file__).


回答 2

os.path.join()可以与一起使用,os.path.sep以创建绝对路径而不是相对路径。

os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox')

os.path.join() can be used in conjunction with os.path.sep to create an absolute rather than relative path.

os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox')

回答 3

除了在引用根目录时,不要在路径组件的开头使用正斜杠:

os.path.join('/home/build/test/sandboxes', todaystr, 'new_sandbox')

另请参见:http : //docs.python.org/library/os.path.html#os.path.join

Do not use forward slashes at the beginning of path components, except when refering to the root directory:

os.path.join('/home/build/test/sandboxes', todaystr, 'new_sandbox')

see also: http://docs.python.org/library/os.path.html#os.path.join


回答 4

为了帮助理解为什么这种令人惊讶的行为并不完全可怕,请考虑接受配置文件名作为参数的应用程序:

config_root = "/etc/myapp.conf/"
file_name = os.path.join(config_root, sys.argv[1])

如果应用程序通过以下方式执行:

$ myapp foo.conf

/etc/myapp.conf/foo.conf将使用配置文件。

但是请考虑使用以下方法调用应用程序会发生什么:

$ myapp /some/path/bar.conf

然后myapp 使用处的配置文件/some/path/bar.conf(而不是/etc/myapp.conf/some/path/bar.conf类似文件)。

可能不是很好,但是我相信这是绝对路径行为的动机。

To help understand why this surprising behavior isn’t entirely terrible, consider an application which accepts a config file name as an argument:

config_root = "/etc/myapp.conf/"
file_name = os.path.join(config_root, sys.argv[1])

If the application is executed with:

$ myapp foo.conf

The config file /etc/myapp.conf/foo.conf will be used.

But consider what happens if the application is called with:

$ myapp /some/path/bar.conf

Then myapp should use the config file at /some/path/bar.conf (and not /etc/myapp.conf/some/path/bar.conf or similar).

It may not be great, but I believe this is the motivation for the absolute path behaviour.


回答 5

这是因为您'/new_sandbox/'以a开头,/因此被假定为相对于根目录。拆下龙头/

It’s because your '/new_sandbox/' begins with a / and thus is assumed to be relative to the root directory. Remove the leading /.


回答 6

为了使您的功能更具可移植性,请按以下方式使用它:

os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox')

要么

os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox')

To make your function more portable, use it as such:

os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox')

or

os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox')

回答 7

尝试使用split("/")和组合*带有现有联接的字符串。

import os

home = '/home/build/test/sandboxes/'
todaystr = '042118'
new = '/new_sandbox/'

os.path.join(*home.split("/"), todaystr, *new.split("/"))


怎么运行的…

split("/") 将现有路径转换为列表: ['', 'home', 'build', 'test', 'sandboxes', '']

* 列表前面的内容将列表中的每个项目分解成自己的参数

Try combo of split("/") and * for strings with existing joins.

import os

home = '/home/build/test/sandboxes/'
todaystr = '042118'
new = '/new_sandbox/'

os.path.join(*home.split("/"), todaystr, *new.split("/"))


How it works…

split("/") turns existing path into list: ['', 'home', 'build', 'test', 'sandboxes', '']

* in front of the list breaks out each item of list its own parameter


回答 8

new_sandbox仅尝试

os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox')

Try with new_sandbox only

os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox')

回答 9

这样做,没有太多的斜线

root="/home"
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox")

do it like this, without too the extra slashes

root="/home"
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox")

回答 10

请注意,如果您使用os.path.join()已经包含点的扩展名,也会遇到类似的问题,当您使用时,扩展名会自动出现os.path.splitext()。在此示例中:

components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)

即使最终您extension可能会得到.jpg一个名为“ foobar”的文件夹,而不是一个名为“ foobar.jpg”的文件。为防止这种情况,您需要单独附加扩展名:

return os.path.join("avatars", instance.username, prefix) + extension

Note that a similar issue can bite you if you use os.path.join() to include an extension that already includes a dot, which is what happens automatically when you use os.path.splitext(). In this example:

components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)

Even though extension might be .jpg you end up with a folder named “foobar” rather than a file called “foobar.jpg”. To prevent this you need to append the extension separately:

return os.path.join("avatars", instance.username, prefix) + extension

回答 11

你可以strip'/'

>>> os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/'.strip('/'))
'/home/build/test/sandboxes/04122019/new_sandbox'

you can strip the '/':

>>> os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/'.strip('/'))
'/home/build/test/sandboxes/04122019/new_sandbox'

回答 12

我建议从第二个和后面的字符串中删除字符串os.path.sep,以防止将它们解释为绝对路径:

first_path_str = '/home/build/test/sandboxes/'
original_other_path_to_append_ls = [todaystr, '/new_sandbox/']
other_path_to_append_ls = [
    i_path.strip(os.path.sep) for i_path in original_other_path_to_append_ls
]
output_path = os.path.join(first_path_str, *other_path_to_append_ls)

I’d recommend to strip from the second and the following strings the string os.path.sep, preventing them to be interpreted as absolute paths:

first_path_str = '/home/build/test/sandboxes/'
original_other_path_to_append_ls = [todaystr, '/new_sandbox/']
other_path_to_append_ls = [
    i_path.strip(os.path.sep) for i_path in original_other_path_to_append_ls
]
output_path = os.path.join(first_path_str, *other_path_to_append_ls)

回答 13

os.path.join("a", *"/b".split(os.sep))
'a/b'

完整版本:

import os

def join (p, f, sep = os.sep):
    f = os.path.normpath(f)
    if p == "":
        return (f);
    else:
        p = os.path.normpath(p)
        return (os.path.join(p, *f.split(os.sep)))

def test (p, f, sep = os.sep):
    print("os.path.join({}, {}) => {}".format(p, f, os.path.join(p, f)))
    print("        join({}, {}) => {}".format(p, f, join(p, f, sep)))

if __name__ == "__main__":
    # /a/b/c for all
    test("\\a\\b", "\\c", "\\") # optionally pass in the sep you are using locally
    test("/a/b", "/c", "/")
    test("/a/b", "c")
    test("/a/b/", "c")
    test("", "/c")
    test("", "c")
os.path.join("a", *"/b".split(os.sep))
'a/b'

a fuller version:

import os

def join (p, f, sep = os.sep):
    f = os.path.normpath(f)
    if p == "":
        return (f);
    else:
        p = os.path.normpath(p)
        return (os.path.join(p, *f.split(os.sep)))

def test (p, f, sep = os.sep):
    print("os.path.join({}, {}) => {}".format(p, f, os.path.join(p, f)))
    print("        join({}, {}) => {}".format(p, f, join(p, f, sep)))

if __name__ == "__main__":
    # /a/b/c for all
    test("\\a\\b", "\\c", "\\") # optionally pass in the sep you are using locally
    test("/a/b", "/c", "/")
    test("/a/b", "c")
    test("/a/b/", "c")
    test("", "/c")
    test("", "c")

从父文件夹导入模块

问题:从父文件夹导入模块

我正在运行Python 2.5。

这是我的文件夹树:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(我还在__init__.py每个文件夹中,为便于阅读,在此省略)

如何nib从模块内部导入life模块?我希望无需修补sys.path就可以做到。

注意:正在运行的主模块在ptdraft文件夹中。

I am running Python 2.5.

This is my folder tree:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(I also have __init__.py in each folder, omitted here for readability)

How do I import the nib module from inside the life module? I am hoping it is possible to do without tinkering with sys.path.

Note: The main module being run is in the ptdraft folder.


回答 0

看来问题与该模块位于父目录或类似目录中无关。

您需要将包含的目录添加ptdraft到PYTHONPATH

您说过import nib与您合作,这可能意味着您将ptdraft自身(而不是其父项)添加到了PYTHONPATH中。

It seems that the problem is not related to the module being in a parent directory or anything like that.

You need to add the directory that contains ptdraft to PYTHONPATH

You said that import nib worked with you, that probably means that you added ptdraft itself (not its parent) to PYTHONPATH.


回答 1

您可以使用相对导入(python> = 2.5):

from ... import nib

(Python 2.5的新增功能)PEP 328:绝对导入和相对导入

编辑:添加了另一个点“。” 上两个包

You could use relative imports (python >= 2.5):

from ... import nib

(What’s New in Python 2.5) PEP 328: Absolute and Relative Imports

EDIT: added another dot ‘.’ to go up two packages


回答 2

相对导入(如中的from .. import mymodule)仅在包中起作用。要导入当前模块的父目录中的“ mymodule”:

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir) 

import mymodule

编辑__file__属性并不总是给定的。os.path.abspath(__file__)我现在建议不要使用Inspect模块来检索当前文件的文件名(和路径),而不要使用它

Relative imports (as in from .. import mymodule) only work in a package. To import ‘mymodule’ that is in the parent directory of your current module:

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir) 

import mymodule

edit: the __file__ attribute is not always given. Instead of using os.path.abspath(__file__) I now suggested using the inspect module to retrieve the filename (and path) of the current file


回答 3

对于同级软件包的导入问题,我也发表了类似的答案。你可以在这里看到它。

没有sys.path黑客的解决方案

摘要

  • 将代码包装到一个文件夹中(例如packaged_stuff
  • setup.py在使用setuptools.setup()的地方使用创建脚本。
  • 使用以下命令以可编辑状态安装软件包 pip install -e <myproject_folder>
  • 导入使用 from packaged_stuff.modulename import function_name

设定

我假设与问题中的文件夹结构相同

.
└── ptdraft
    ├── __init__.py
    ├── nib.py
    └── simulations
        ├── __init__.py
        └── life
            ├── __init__.py
            └── life.py

我将其.称为根文件夹,就我而言,它位于中C:\tmp\test_imports

脚步

1)将A添加setup.py到根文件夹

的内容setup.py可以很简单

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages())

基本上是“任何” setup.py都可以。这只是一个最小的工作示例。

2)使用虚拟环境

如果您熟悉虚拟环境,请激活一个,然后跳到下一步。虚拟环境的使用不是绝对必需的,但从长远来看(当您正在进行多个项目时),它们确实可以帮助您。最基本的步骤是(在根文件夹中运行)

  • 创建虚拟环境
    • python -m venv venv
  • 激活虚拟环境
    • . /venv/bin/activate(Linux)或./venv/Scripts/activate(Win)

要了解更多有关此的信息,只需在Google上搜索“ python virtualenv教程”或类似内容即可。除了创建,激活和停用之外,您可能根本不需要任何其他命令。

创建并激活虚拟环境后,控制台应在括号中提供虚拟环境的名称。

PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>

3)pip以可编辑状态安装项目

安装您的顶级包myproject使用pip。诀窍是-e在执行安装时使用标志。这样,它以可编辑状态安装,并且对.py文件所做的所有编辑将自动包含在已安装的软件包中。

在根目录中,运行

pip install -e . (注意点,它代表“当前目录”)

您还可以看到它是通过使用安装的 pip freeze

(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
  Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0

4)通过mainfolder在每次导入之前进行导入

在此示例中,mainfolder将为ptdraft。这样的好处是您不会与其他模块名称(来自python标准库或3rd party模块)发生名称冲突。


用法示例

笔尖

def function_from_nib():
    print('I am the return value from function_from_nib!')

life.py

from ptdraft.nib import function_from_nib

if __name__ == '__main__':
    function_from_nib()

运行life.py

(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!

I posted a similar answer also to the question regarding imports from sibling packages. You can see it here.

Solution without sys.path hacks

Summary

  • Wrap the code into one folder (e.g. packaged_stuff)
  • Use create setup.py script where you use setuptools.setup().
  • Pip install the package in editable state with pip install -e <myproject_folder>
  • Import using from packaged_stuff.modulename import function_name

Setup

I assume the same folder structure as in the question

.
└── ptdraft
    ├── __init__.py
    ├── nib.py
    └── simulations
        ├── __init__.py
        └── life
            ├── __init__.py
            └── life.py

I call the . the root folder, and in my case it is located in C:\tmp\test_imports.

Steps

1) Add a setup.py to the root folder

The contents of the setup.py can be simply

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages())

Basically “any” setup.py would work. This is just a minimal working example.

2) Use a virtual environment

If you are familiar with virtual environments, activate one, and skip to the next step. Usage of virtual environments are not absolutely required, but they will really help you out in the long run (when you have more than 1 project ongoing..). The most basic steps are (run in the root folder)

  • Create virtual env
    • python -m venv venv
  • Activate virtual env
    • . /venv/bin/activate (Linux) or ./venv/Scripts/activate (Win)

To learn more about this, just Google out “python virtualenv tutorial” or similar. You probably never need any other commands than creating, activating and deactivating.

Once you have made and activated a virtual environment, your console should give the name of the virtual environment in parenthesis

PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>

3) pip install your project in editable state

Install your top level package myproject using pip. The trick is to use the -e flag when doing the install. This way it is installed in an editable state, and all the edits made to the .py files will be automatically included in the installed package.

In the root directory, run

pip install -e . (note the dot, it stands for “current directory”)

You can also see that it is installed by using pip freeze

(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
  Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0

4) Import by prepending mainfolder to every import

In this example, the mainfolder would be ptdraft. This has the advantage that you will not run into name collisions with other module names (from python standard library or 3rd party modules).


Example Usage

nib.py

def function_from_nib():
    print('I am the return value from function_from_nib!')

life.py

from ptdraft.nib import function_from_nib

if __name__ == '__main__':
    function_from_nib()

Running life.py

(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!

回答 4

您可以在sys.path中列出的“模块搜索路径”中使用取决于OS的路径。因此您可以轻松添加父目录,如下所示

import sys
sys.path.insert(0,'..')

如果您要添加父/母目录,

sys.path.insert(0,'../..')

这在python 2和3。

You can use OS depending path in “module search path” which is listed in sys.path . So you can easily add parent directory like following

import sys
sys.path.insert(0,'..')

If you want to add parent-parent directory,

sys.path.insert(0,'../..')

This works both in python 2 and 3.


回答 5

如果无法将模块文件夹添加到PYTHONPATH,则可以在程序中修改sys.path列表,Python解释程序会在其中搜索要导入的模块,python文档说:

导入名为spam的模块时,解释器首先搜索具有该名称的内置模块。如果找不到,它将在变量sys.path给出的目录列表中搜索名为spam.py的文件。sys.path从以下位置初始化:

  • 包含输入脚本的目录(或当前目录)。
  • PYTHONPATH(目录名称列表,语法与shell变量PATH相同)。
  • 取决于安装的默认值。

初始化之后,Python程序可以修改sys.path。包含正在运行的脚本的目录位于搜索路径的开始,在标准库路径之前。这意味着将加载该目录中的脚本,而不是库目录中相同名称的模块。除非打算进行更换,否则这是一个错误。

知道了这一点,您可以在程序中执行以下操作:

import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')

# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft

If adding your module folder to the PYTHONPATH didn’t work, You can modify the sys.path list in your program where the Python interpreter searches for the modules to import, the python documentation says:

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • the directory containing the input script (or the current directory).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • the installation-dependent default.

After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended.

Knowing this, you can do the following in your program:

import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')

# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft

回答 6

对python 2不太了解。
在python 3中,可以按以下方式添加父文件夹:

import sys 
sys.path.append('..')

…然后可以从中导入模块

Don’t know much about python 2.
In python 3, the parent folder can be added as follows:

import sys 
sys.path.append('..')

…and then one is able to import modules from it


回答 7

这是一个简单的答案,因此您可以了解它的工作原理(小型和跨平台)。
它仅使用内置模块(ossysinspect),所以应该工作
在任何操作系统(OS),因为Python是专为上。

较短的答案代码-更少的行和变量

from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module  # Replace "my_module" here with the module name.
sys.path.pop(0)

如果少于此行,请用替换第二行import os.path as path, sys, inspect,在(第3行)的开头
添加inspect.getsourcefile然后删除第一行。
-但是,这会导入所有模块,因此可能需要更多的时间,内存和资源。

我的答案的代码(较长版本

from inspect import getsourcefile
import os.path
import sys

current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]

sys.path.insert(0, parent_dir)

import my_module  # Replace "my_module" here with the module name.

它使用来自Stack Overflow答案的示例。如何获取
Python中当前执行文件的路径?
使用内置工具查找正在运行的代码的源(文件名)。

from inspect import getsourcefile  
from os.path import abspath  

接下来,无论您想在哪里找到源文件,都只需使用:

abspath(getsourcefile(lambda:0))

我的代码sys.path在的python路径列表中添加了文件路径
因为这允许Python从该文件夹导入模块。

在代码中导入模块之后, 当添加的文件夹中的模块名称与另一个 稍后在程序中导入的模块同名时,最好sys.path.pop(0)换行运行。您需要删除导入之前添加的列表项,而不是其他路径。 如果您的程序未导入其他模块,则不删除文件路径是安全的,因为 在程序结束(或重新启动Python Shell)之后,对



sys.path消失。

有关文件名变量的注释

我的答案没有使用__file__变量来获取正在运行的
代码的文件路径/文件名,因为此处的用户经常将其描述为不可靠的。您不应将其
用于其他人使用的程序中从父文件夹导入模块

一些不起作用的示例(引用 Stack Overflow问题):

• 在某些平台找不到•有时不是完整的文件路径

  • py2exe没有__file__属性,但是有一种解决方法
  • 当您从IDLE运行时,execute()没有__file__属性
  • 我得到的OS X 10.6 NameError: global name '__file__' is not defined

Here is an answer that’s simple so you can see how it works, small and cross-platform.
It only uses built-in modules (os, sys and inspect) so should work
on any operating system (OS) because Python is designed for that.

Shorter code for answer – fewer lines and variables

from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module  # Replace "my_module" here with the module name.
sys.path.pop(0)

For less lines than this, replace the second line with import os.path as path, sys, inspect,
add inspect. at the start of getsourcefile (line 3) and remove the first line.
– however this imports all of the module so could need more time, memory and resources.

The code for my answer (longer version)

from inspect import getsourcefile
import os.path
import sys

current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]

sys.path.insert(0, parent_dir)

import my_module  # Replace "my_module" here with the module name.

It uses an example from a Stack Overflow answer How do I get the path of the current
executed file in Python?
to find the source (filename) of running code with a built-in tool.

from inspect import getsourcefile  
from os.path import abspath  

Next, wherever you want to find the source file from you just use:

abspath(getsourcefile(lambda:0))

My code adds a file path to sys.path, the python path list
because this allows Python to import modules from that folder.

After importing a module in the code, it’s a good idea to run sys.path.pop(0) on a new line
when that added folder has a module with the same name as another module that is imported
later in the program. You need to remove the list item added before the import, not other paths.
If your program doesn’t import other modules, it’s safe to not delete the file path because
after a program ends (or restarting the Python shell), any edits made to sys.path disappear.

Notes about a filename variable

My answer doesn’t use the __file__ variable to get the file path/filename of running
code because users here have often described it as unreliable. You shouldn’t use it
for importing modules from parent folder in programs used by other people.

Some examples where it doesn’t work (quote from this Stack Overflow question):

• it can’t be found on some platforms • it sometimes isn’t the full file path

  • py2exe doesn’t have a __file__ attribute, but there is a workaround
  • When you run from IDLE with execute() there is no __file__ attribute
  • OS X 10.6 where I get NameError: global name '__file__' is not defined

回答 8

这是更通用的解决方案,其中将父目录包含在sys.path中(对我有用):

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

Here is more generic solution that includes the parent directory into sys.path (works for me):

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

回答 9

我发现以下方法可用于从脚本的父目录导入包。在示例中,我想env.pyapp.db包中导入函数。

.
└── my_application
    └── alembic
        └── env.py
    └── app
        ├── __init__.py
        └── db
import os
import sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

I found the following way works for importing a package from the script’s parent directory. In the example, I would like to import functions in env.py from app.db package.

.
└── my_application
    └── alembic
        └── env.py
    └── app
        ├── __init__.py
        └── db
import os
import sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

回答 10

上述解决方案也很好。解决此问题的另一种方法是

如果要从顶层目录导入任何内容。然后,

from ...module_name import *

另外,如果要从父目录导入任何模块。然后,

from ..module_name import *

另外,如果要从父目录导入任何模块。然后,

from ...module_name.another_module import *

这样,您可以根据需要导入任何特定方法。

Above mentioned solutions are also fine. Another solution to this problem is

If you want to import anything from top level directory. Then,

from ...module_name import *

Also, if you want to import any module from the parent directory. Then,

from ..module_name import *

Also, if you want to import any module from the parent directory. Then,

from ...module_name.another_module import *

This way you can import any particular method if you want to.


回答 11

对我来说,访问父目录最短和最喜欢的oneliner是:

sys.path.append(os.path.dirname(os.getcwd()))

要么:

sys.path.insert(1, os.path.dirname(os.getcwd()))

os.getcwd()返回当前工作目录的名称,os.path.dirname(directory_name)返回所传递目录的目录名称。

实际上,在我看来,Python项目体系结构应采用以下方式:子目录中的任何模块都不会使用父目录中的任何模块。如果发生这种情况,则值得重新考虑项目树。

另一种方法是将父目录添加到PYTHONPATH系统环境变量。

For me the shortest and my favorite oneliner for accessing to the parent directory is:

sys.path.append(os.path.dirname(os.getcwd()))

or:

sys.path.insert(1, os.path.dirname(os.getcwd()))

os.getcwd() returns the name of the current working directory, os.path.dirname(directory_name) returns the directory name for the passed one.

Actually, in my opinion Python project architecture should be done the way where no one module from child directory will use any module from the parent directory. If something like this happens it is worth to rethink about the project tree.

Another way is to add parent directory to PYTHONPATH system environment variable.


回答 12

在Jupyter笔记本中

只要您在Jupyter Notebook中工作,这个简短的解决方案就可能有用:

%cd ..
import nib

即使没有__init__.py文件也可以使用。

我在Linux和Windows 7上使用Anaconda3对其进行了测试。

In a Jupyter Notebook

As long as you’re working in a Jupyter Notebook, this short solution might be useful:

%cd ..
import nib

It works even without an __init__.py file.

I tested it with Anaconda3 on Linux and Windows 7.


回答 13

import sys sys.path.append('../')

import sys sys.path.append('../')


回答 14

当不在带有__init__.py文件的打包环境中时,pathlib库(包含在> = Python 3.4中)使将父目录的路径附加到PYTHONPATH变得非常简洁直观:

import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))

When not being in a package environment with __init__.py files the pathlib library (included with >= Python 3.4) makes it very concise and intuitive to append the path of the parent directory to the PYTHONPATH:

import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))

回答 15

与过去的答案相同的风格-但行数较少:P

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

文件返回您正在工作的位置

same sort of style as the past answer – but in fewer lines :P

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

file returns the location you are working in


回答 16

使用库。创建一个名为nib的库,使用setup.py安装它,使其驻留在站点程序包中,您的问题将得到解决。您不必将自己制作的所有东西都塞进一个包装中。分解成碎片。

Work with libraries. Make a library called nib, install it using setup.py, let it reside in site-packages and your problems are solved. You don’t have to stuff everything you make in a single package. Break it up to pieces.


回答 17

在Linux系统中,您可以创建一个从“ life”文件夹到nib.py文件的软链接。然后,您可以像这样简单地导入它:

import nib

In a Linux system, you can create a soft link from the “life” folder to the nib.py file. Then, you can simply import it like:

import nib