source

모듈 경로를 검색하는 방법

bestscript 2023. 1. 6. 19:54

모듈 경로를 검색하는 방법

모듈 변경 여부를 검출하고 싶습니다.이제 inotify를 사용하는 것은 간단합니다.통지를 받을 디렉토리를 알면 됩니다.

python에서 모듈의 경로를 검색하려면 어떻게 해야 합니까?

import a_module
print(a_module.__file__)

적어도 Mac OS X에서는 로드된 .pyc 파일에 대한 경로를 제공합니다. 따라서 다음을 수행할 수 있습니다.

import os
path = os.path.abspath(a_module.__file__)

다음의 조작도 가능합니다.

path = os.path.dirname(a_module.__file__)

모듈의 디렉토리를 가져옵니다.

inspect비단뱀

공식 문서

인스펙션모듈에는 모듈, 클래스, 메서드, 함수, 트레이스백, 프레임오브젝트, 코드오브젝트 등의 라이브오브젝트에 대한 정보를 취득하는데 도움이 되는 몇 가지 유용한 기능이 있습니다.예를 들어 클래스의 내용을 검사하거나 메서드의 소스 코드를 가져오거나 함수의 인수 목록을 추출 및 포맷하거나 자세한 트레이스백을 표시하는 데 필요한 모든 정보를 얻는 데 도움이 됩니다.

예:

>>> import os
>>> import inspect
>>> inspect.getfile(os)
'/usr/lib64/python2.7/os.pyc'
>>> inspect.getfile(inspect)
'/usr/lib64/python2.7/inspect.pyc'
>>> os.path.dirname(inspect.getfile(inspect))
'/usr/lib64/python2.7'

다른 답변에서도 언급되었듯이, 이를 위한 최선의 방법은__file__(서양속담, 친구속담)하지만 중요한 경고가 있습니다. 을 사용하다__file__하고 있는 「」, 「」, 「」)는 존재하지 않습니다.__main__를 참조해 주세요.

예를 들어 PYTONPATH에 두 개의 파일이 있다고 가정합니다.

#/path1/foo.py
import bar
print(bar.__file__)

그리고.

#/path2/bar.py
import os
print(os.getcwd())
print(__file__)

foo.py 를 실행하면 다음과 같은 출력이 나타납니다.

/path1        # "import bar" causes the line "print(os.getcwd())" to run
/path2/bar.py # then "print(__file__)" runs
/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs

다만, bar.py 를 단독으로 실행하려고 하면, 다음과 같이 됩니다.

/path2                              # "print(os.getcwd())" still works fine
Traceback (most recent call last):  # but __file__ doesn't exist if bar.py is running as main
  File "/path2/bar.py", line 3, in <module>
    print(__file__)
NameError: name '__file__' is not defined 

이게 도움이 됐으면 좋겠다.이 경고로 인해 제시된 다른 솔루션을 테스트하는 데 많은 시간과 혼란이 들었습니다.

이 문제에 대해서도 몇 가지 변형을 시험해 보겠습니다.

  1. 호출된 스크립트의 경로 찾기
  2. 현재 실행 중인 스크립트의 경로 찾기
  3. 호출된 스크립트의 디렉터리 찾기

(이러한 질문 중 일부는 SO에 대해 질문되었으나 중복으로 종결되어 여기로 리디렉션되었습니다.)

__file__

Import한 모듈의 경우:

import something
something.__file__ 

는 모듈의 절대 경로를 반환합니다.하지만, 다음 대본 foo를 보면.py:

#foo.py
print '__file__', __file__

'http://foo.py'로 전화를 걸면 단순히 'foo.py'이 반환됩니다.shebang을 추가하는 경우:

#!/usr/bin/python 
#foo.py
print '__file__', __file__

./foo.py을 사용하여 호출하면 '.foo.py'이 반환됩니다.다른 디렉토리에서 호출(예를 들어 디렉토리 바에 foo.py을 저장)한 후 다음 중 하나를 호출합니다.

python bar/foo.py

또는 shebang을 추가하고 파일을 직접 실행합니다.

bar/foo.py

는, 「bar/foo.py」(상대 패스)를 반환합니다.

디렉토리 검색

서부터 디렉토리 「」를 합니다.os.path.dirname(__file__)까다로울 수도 있습니다.적어도 내 시스템에서는 파일과 같은 디렉토리에서 호출하면 빈 문자열이 반환됩니다.★★★★★★★★★★★★★★★★★,

# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)

출력:

__file__ is: foo.py
os.path.dirname(__file__) is: 

즉, 빈 문자열이 반환되므로 Import된 모듈의 파일이 아닌 현재 파일에 사용할 경우 신뢰성이 없는 것으로 보입니다.이 문제를 회피하려면 , 다음의 콜에 랩 해 주세요.

# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))

출력은 다음과 같습니다.

os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar

abspath()는 심볼링크를 해결할 수 없습니다.이를 수행하려면 대신 realpath()를 사용합니다.예를 들어, 다음과 같은 내용으로 file_import_testing.py를 가리키는 심볼 링크 file_import_testing_link를 만듭니다.

import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)

를 실행하면 다음과 같은 절대 경로가 인쇄됩니다.

abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py

file_import_syslog_link -> file_import_syslog.화이

검사 사용

@SummerBreeze는 검사 모듈의 사용을 언급하고 있습니다.

이는 Import된 모듈에서는 매우 간결하게 기능하는 것으로 보입니다.

import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)

순순히 절대 경로를 반환합니다.현재 실행 중인 스크립트의 경로를 찾으려면:

inspect.getfile(inspect.currentframe())

(고마워 @jbochi)

inspect.getabsfile(inspect.currentframe()) 

에 현재 실행 중인 스크립트의 절대 경로를 나타냅니다(@Sadman_Sakib 감사합니다).

왜 아무도 이 문제에 대해 언급하지 않는지 모르겠습니다만, 가장 간단한 해결책은 imp.find_module("modulename")사용하는 것입니다(여기 문서 참조).

import imp
imp.find_module("os")

패스가 두 번째 위치에 있는 태플을 제공합니다.

(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,
'/usr/lib/python2.7/os.py',
('.py', 'U', 1))

"inspect" 메서드에 비해 이 메서드는 모듈을 Import할 필요가 없으며 입력에 문자열을 사용할 수 있다는 장점이 있습니다.예를 들어 다른 스크립트를 호출한 모듈을 체크할 때 유용합니다.

편집:

python3의 importlib모듈은 다음 작업을 수행합니다.

★★의 importlib.util.find_spec:

지정된 모듈의 사양을 반환합니다.

먼저 sys.modules를 체크하여 모듈이 이미 Import되었는지 확인합니다.이 경우 sys.modules[name]를 선택합니다.spec이 반환됩니다.이 값이 [None]으로 설정되어 있으면 ValueError가 발생합니다.모듈이 sys.modules에 없는 경우 sys.meta_path는 finder에 'path' 값이 지정된 적절한 사양을 검색합니다.규격을 찾을 수 없으면 아무것도 반환되지 않습니다.

서브모듈의 이름(도트 포함)인 경우 부모 모듈은 자동으로 Import됩니다.

name 인수 및 package 인수는 importlib.import_module()과 동일하게 동작합니다.즉, 상대 모듈 이름(선행 도트 포함)이 기능합니다.

이건 사소했어요.

에는 ''가 .__file__현재 위치에서 상대 경로를 나타내는 변수입니다.

따라서 모듈이 이를 통지하기 위한 디렉토리를 얻는 방법은 다음과 같습니다.

os.path.dirname(__file__)
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
import module
print module.__path__

는 또 아트리뷰트 「」를 하고 있습니다.__path__의 「」, 「」가 유지되고 있는 로 초기화됩니다.__init__.py 패키지에 에 영향을 .이 변수는 변경할 수 있습니다.변경하면 패키지에 포함된 모듈 및 서브패키지의 향후 검색에 영향을 미칩니다.

이 기능은 자주 필요하지 않지만 패키지에 포함된 모듈 세트를 확장하는 데 사용할 수 있습니다.

원천

명령줄 유틸리티

명령줄 유틸리티로 변경할 수 있습니다.

python-which <package name>

여기에 이미지 설명 입력


/usr/local/bin/python-which

#!/usr/bin/env python

import importlib
import os
import sys

args = sys.argv[1:]
if len(args) > 0:
    module = importlib.import_module(args[0])
    print os.path.dirname(module.__file__)

실행 가능한 것으로 하다

sudo chmod +x /usr/local/bin/python-which

모듈을 Import한 후 이름을 누르면 전체 경로를 얻을 수 있습니다.

>>> import os
>>> os
<module 'os' from 'C:\\Users\\Hassan Ashraf\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\os.py'>
>>>

그래서 py2exe를 사용하여 이 작업을 수행하는데 상당한 시간을 소비했습니다. 문제는 스크립트의 기본 폴더를 python 스크립트로 실행하든 py2exe 실행 파일로 실행하든 간에 가져오는 것이었습니다.또한 현재 폴더, 다른 폴더 또는 시스템 경로에서 실행 중인지 여부에 관계없이 작동하도록 합니다.

결국 저는 py2exe 실행 인디케이터로 sys.frozen을 사용하여 다음 방법을 사용했습니다.

import os,sys
if hasattr(sys,'frozen'): # only when running in py2exe this exists
    base = sys.prefix
else: # otherwise this is a regular python script
    base = os.path.dirname(os.path.realpath(__file__))

패키지 모듈 중 하나에서 패키지 루트 경로를 가져오려면 다음 작업을 수행합니다(Python 3.6에서 테스트됨).

from . import __path__ as ROOT_PATH
print(ROOT_PATH)

★★★__init__.py할 수도 .__file__★★★★★★ 。

이게 도움이 됐으면 좋겠네요!

모듈 경로를 로드하지 않고 가져오는 경우:

import importlib.util

print(importlib.util.find_spec("requests").origin)

출력 예:

/usr/lib64/python3.9/site-packages/requests/__init__.py

스크립트에서 절대 경로를 확인하려면 Path 개체를 사용할 수 있습니다.

from pathlib import Path

print(Path().absolute())
print(Path().resolve('.'))
print(Path().cwd())

cwd() 메서드

현재 디렉토리를 나타내는 새 경로 개체를 반환합니다(os.getcwd()에서 반환).

resolve() 메서드

경로를 절대 경로로 설정하여 심볼 링크를 해결합니다.새 경로 개체가 반환됩니다.

수입하다 아웃 ★★★★dir(a_module)a_module.__path__모듈 자체를 인쇄할 수도 있습니다.

>>> import a_module
>>> print(dir(a_module))
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> print(a_module.__path__)
['/.../.../a_module']
>>> print(a_module)
<module 'a_module' from '/.../.../a_module/__init__.py'>

할 때 이 있다면__file__현재 상대 디렉토리가 공백인 경우(즉, 스크립트가 있는 디렉토리와 같은 디렉토리에서 스크립트로 실행 중인 경우), 간단한 해결 방법은 다음과 같습니다.

import os.path
mydir = os.path.dirname(__file__) or '.'
full  = os.path.abspath(mydir)
print __file__, mydir, full

그 결과:

$ python teste.py 
teste.py . /home/user/work/teste

은 에 있다or '.'dirname()가 출합니다다 the로 됩니다. 디르.이는 현재 디렉토리를 의미하며 경로 관련 기능에 유효한 디렉토리입니다.

이렇게 '마지막으로abspath()을 사용하다그러나 이 방법을 사용할 경우 요령은 필요하지 않습니다.abspath()는 빈 경로를 받아들여 현재 디렉토리로 적절하게 해석합니다.

하나의 일반적인 시나리오(Python 3의 경우)에 기고하여 몇 가지 접근법에 대해 알아보겠습니다.

삽입 함수 open()은 첫 번째 인수로 상대 경로 또는 절대 경로 중 하나를 받아들입니다.다만, 상대 패스는 현재의 작업 디렉토리에 대해서 상대 패스로 취급되기 때문에, 파일에 절대 패스를 건네주는 것을 추천합니다.

간단히 말하면, 다음 코드로 스크립트파일을 실행하는 경우,example.txt스크립트 파일이 있는 디렉토리와 같은 디렉토리에 파일이 생성됩니다.

with open('example.txt', 'w'):
    pass

이 코드를 수정하려면 스크립트에 대한 경로를 가져와 절대 경로를 만들어야 합니다.경로가 절대적이 되도록 하기 위해 os.path.realpath() 함수를 사용합니다.스크립트에 대한 경로를 얻기 위해 다양한 경로 결과를 반환하는 몇 가지 일반적인 함수가 있습니다.

  • os.getcwd()
  • os.path.realpath('example.txt')
  • sys.argv[0]
  • __file__

os.getcwd() 및 os.path.realpath() 함수는 모두 현재 작업 디렉토리를 기반으로 경로 결과를 반환합니다.일반적으로 우리가 원하는 것은 아니다.sys.argv 목록의 첫 번째 요소는 루트 스크립트 자체 또는 해당 모듈 중 어느 쪽이든 목록을 호출하든 관계없이 루트 스크립트(실행하는 스크립트)의 경로입니다.경우에 따라서는 편리할 수도 있습니다.__file__ 변수에는 호출된 모듈의 경로가 포함됩니다.


는 올바르게 .example.txt스크립트가 있는 디렉토리와 같은 디렉토리:

filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')

with open(filepath, 'w'):
    pass

pip을 사용하여 설치한 경우 "pip show" ('장소')가 올바르게 작동합니다.

$p show detectron2

Name: detectron2
Version: 0.1
Summary: Detectron2 is FAIR next-generation research platform for object detection and segmentation.
Home-page: https://github.com/facebookresearch/detectron2
Author: FAIR
Author-email: None
License: UNKNOWN
Location: /home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages
Requires: yacs, tabulate, tqdm, pydot, tensorboard, Pillow, termcolor, future, cloudpickle, matplotlib, fvcore

업데이트:

$ python - m pip show mymodule

(작성자: wisbucky)

python 패키지의 모듈 내에서 패키지와 같은 디렉토리에 있는 파일을 참조해야 했습니다.예.

some_dir/
  maincli.py
  top_package/
    __init__.py
    level_one_a/
      __init__.py
      my_lib_a.py
      level_two/
        __init__.py
        hello_world.py
    level_one_b/
      __init__.py
      my_lib_b.py

그래서 위의 경우 top_lib_a.py 모듈에서 maincli.py으로 전화해야 했습니다.이때 top_lib_a.py와 maincli.py이 같은 디렉토리에 있는 것을 알고 있었습니다.maincli에 대한 경로는 다음과 같습니다.py:

import sys
import os
import imp


class ConfigurationException(Exception):
    pass


# inside of my_lib_a.py
def get_maincli_path():
    maincli_path = os.path.abspath(imp.find_module('maincli')[1])
    # top_package = __package__.split('.')[0]
    # mod = sys.modules.get(top_package)
    # modfile = mod.__file__
    # pkg_in_dir = os.path.dirname(os.path.dirname(os.path.abspath(modfile)))
    # maincli_path = os.path.join(pkg_in_dir, 'maincli.py')

    if not os.path.exists(maincli_path):
        err_msg = 'This script expects that "maincli.py" be installed to the '\
        'same directory: "{0}"'.format(maincli_path)
        raise ConfigurationException(err_msg)

    return maincli_path

Plasma Binturong의 투고를 바탕으로 코드를 수정하였습니다.

이것을 「프로그램」으로 동적으로 실시하려면 , 다음의 코드를 사용해 주세요.
내 말은, 당신은 그것을 "하드코드"하기 위한 정확한 모듈의 이름을 모를 수도 있다는 것이다.목록에서 선택하거나 __file_을(를) 사용하기 위해 현재 실행 중이 아닐 수 있습니다.

(Python 3에서는 동작하지 않는 것을 알고 있습니다.

global modpath
modname = 'os' #This can be any module name on the fly
#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()
#Call the file with execfile()
execfile('modname.py')
print modpath
<module 'os' from 'C:\Python27\lib\os.pyc'>

저는 "글로벌" 문제를 없애려고 노력했지만, 작동하지 않는 경우를 발견하였습니다. "execfile()"은 Python 3에서 에뮬레이트 할 수 있다고 생각합니다.이것은 프로그램 내에 있기 때문에 재사용을 위해 메서드나 모듈에 쉽게 넣을 수 있습니다.

쾅하고 때리다를 하여 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」pushd규범에 준거합니다.

#!/bin/bash
module=${1:?"I need a module name"}

python << EOI
import $module
import os
print os.path.dirname($module.__file__)
EOI

셸의 예:

[root@sri-4625-0004 ~]# export LXML=$(get_python_path.sh lxml)
[root@sri-4625-0004 ~]# echo $LXML
/usr/lib64/python2.7/site-packages/lxml
[root@sri-4625-0004 ~]#

등:pandas디렉토리를 취득할 때는 이것을 추천합니다(Import가 모듈인 경우, 예를 들어 다음과 같이 동작하지 않습니다). pathlib

from importlib import resources  # part of core Python
import pandas as pd

package_dir = resources.path(package=pd, resource="").__enter__()

일반적으로 importlib.resources는 사이트 패키지의 경로/리소스에 액세스하는 태스크인 경우 고려할 수 있습니다.

「 」를 pip를 호출하면, 「」를 할 수 pip show, 인 을 사용하여 python사용할 수 있습니다.예를 들어 다음과 같은 결과가 모두 다를 수 있습니다.

$ python -m pip show numpy
$ python2.7 -m pip show numpy
$ python3 -m pip show numpy

Location: /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python

$ pip show numpy, pip 정도로 다르다python호출하고 있습니다.

언급URL : https://stackoverflow.com/questions/247770/how-to-retrieve-a-modules-path