Как мне получить доступ к файлу не зная точного расположения файла вызова кода
У меня есть функция которую я храню в файле например fun.py
Код этой функций мне нужен в разных файла и мне приходится постоянно
создавать копию файла рядом с файлом который я запускаю а после выполнять
from . fun import myfun
Директория
\project
\folder1
fun.py
run1.py
\folder2
fun.py
run2.py
И это крайне неудобно и занимает лишнее место и что бы этого избежать
Я хочу хранить только один файл fun.py в папке \project и после получать к ниму доступ
Например как здесь
fun.py
def myfun():
print('!!! Hello myfun !!!\n')
run.py
import sys
sys.path += [r'C:\project']
from fun import myfun
myfun()
Директория
\project
fun.py
\folder1
\folder2
run.py
или
\project
fun.py
\folder1
\folder2
run.py
позиция run.py может быть любой
Но проблема такого метода в том что как только я перемещу папку \project в другое место
мне придется переписывать все пути sys.path снова
Как я могу сделать все правильно что бы не переписывать все и не засорять проэкт лишними файлами?
Ответы (2 шт):
По умолчанию вы не можете. При импорте файла Python ищет только текущий каталог, каталог, из которого выполняется точка входа script, и sys.path, который включает в себя такие места, как каталог установки пакета (он на самом деле немного сложнее, чем этот, но это охватывает большинство случаев).
Однако вы можете добавить к пути Python во время выполнения(это пример):
some_file.py
import sys
sys.path.insert(0, '/path/to/application/app/folder')
import file
Если я вас правильно понял и если fun.py запускать из каталога path/project, то это может выглядеть примерно так:
fun.py
import sys
import os
def myfun(): # <---
print('!!! Hello myfun !!!\n')
def passage(file_name, folder):
for element in os.scandir(folder):
if element.is_file():
if element.name == file_name:
yield folder
else:
yield from passage(file_name, element.path)
_path = list(passage('run.py', os.getcwd()))
if _path:
path_run = _path[0]
sys.path.append(os.path.realpath(path_run)) # <---
import run # <---
run.py
print('\nHello run.py\n')
from fun import myfun
myfun() # <---
Update
Наоборот мне нужно запустить файл run.py, и уже от него получить доступ к fun.py. Я поправил вопрос
Добавьте в папку path/project модуль main.py и запустите его:
main.py
import sys
import os
def passage(file_name, folder):
for element in os.scandir(folder):
if element.is_file():
if element.name == file_name:
yield folder
else:
yield from passage(file_name, element.path)
_path = list(passage('run.py', os.getcwd()))
if _path:
path_run = _path[0]
sys.path.append(os.path.realpath(path_run)) # <---
import run # <---
run.py
print('\nHello run.py\n')
from fun import myfun
myfun() # <---
fun.py
def myfun(): # <---
print('!!! Hello myfun !!!\n')

