විවිධ ෆෝල්ඩරයෙන් ගොනු ආයාත කිරීම


1464

මට පහත ෆෝල්ඩර ව්‍යුහය ඇත.

application/app/folder/file.py

වෙනත් පයිතන් ගොනුවක file.py වෙතින් සමහර කාර්යයන් ආනයනය කිරීමට මට අවශ්‍යය

application/app2/some_folder/some_file.py

මම උත්සාහ කළා

from application.app.folder.file import func_name

සහ වෙනත් විවිධ උත්සාහයන් නමුත් මෙතෙක් මට නිසි ලෙස ආනයනය කිරීමට නොහැකි විය. මට මෙය කළ හැක්කේ කෙසේද?


2
ආශ්‍රිත: stackoverflow.com/q/43476403/674039
wim

නිල ලියකියවිලි කියවීම මට බොහෝ සෙයින් උපකාරී විය! docs.python.org/3/reference/…
කවින් රාජු එස්

Answers:


1506

පෙරනිමියෙන්, ඔබට බැහැ. ගොනුවක් ආයාත කරන විට, පයිතන් සොයන්නේ වත්මන් නාමාවලිය, පිවිසුම් ලක්ෂ්‍ය ස්ක්‍රිප්ට් ක්‍රියාත්මක වන sys.pathනාමාවලිය සහ පැකේජ ස්ථාපන නාමාවලිය වැනි ස්ථාන ඇතුළත් වේ (එය ඇත්ත වශයෙන්ම මෙයට වඩා ටිකක් සංකීර්ණයි, නමුත් මෙය බොහෝ අවස්ථාවන් ආවරණය කරයි) .

කෙසේ වෙතත්, ඔබට ධාවන වේලාවේදී පයිතන් මාර්ගයට එක් කළ හැකිය:

# some_file.py
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')

import file

370
sys.path.append('/path/to/application/app/folder')is cleaner imo
pseudosudo

397
@pseudosudo: ඔව්, නමුත් එය ආරම්භයේදීම ඇතුළත් කිරීමෙන් ගැටුම් නම් කිරීමේ දී අනෙක් අය ඉදිරියේ (ගොඩනඟන ලද ඒවා පවා) ගවේෂණය කර ඇති බවට සහතික වීමේ වාසිය ඇත.
කැමරන්

8
reakreativitea - sys.patha listනොව a නැවත ලබා දෙන dequeඅතර එය lista dequeසහ back බවට පරිවර්තනය කිරීම මෝඩකමක් වනු ඇත.
ArtOfWarfare

39
ෆෝල්ඩර වල .py ගොනු කළමනාකරණය කිරීම පයිතොනික් ක්‍රමයක් ලෙස සලකන්නේද? මම කල්පනා කරනවා ... ඇයි එය පෙරනිමියෙන් සහාය නොදක්වන්නේ? සියලුම .py ගොනු තනි ඩිරෙක්ටරියක් තුළ පවත්වාගෙන යාමේ තේරුමක් නැත ..
Ofir

52
F ඕෆීර්: නැත, මෙය හොඳ පිරිසිදු පයිතොනික් විසඳුමක් නොවේ. පොදුවේ, ඔබ ඇසුරුම් භාවිතා කළ යුතුය (ඒවා නාමාවලි ගස් මත පදනම් වේ). මෙම පිළිතුර අසන ලද ප්‍රශ්නයට විශේෂිත වූ අතර කිසියම් හේතුවක් නිසා දිගින් දිගටම ඉහළ සංඛ්‍යාවක් ලබා ගනී.
කැමරන්

737

වරදක් නැත:

from application.app.folder.file import func_name

එය folderද අඩංගු බවට වග බලා ගන්න __init__.py, මෙය පැකේජයක් ලෙස ඇතුළත් කිරීමට ඉඩ දෙයි. අනෙක් පිළිතුරු ගැන කතා කරන්නේ ඇයිදැයි විශ්වාස නැත PYTHONPATH.


48
වෙනස් PYTHONPATHකිරීම අවශ්‍ය වන අවස්ථා මෙය ආවරණය නොකරන බැවිනි . ඔබට එකම මට්ටමේ ෆෝල්ඩර දෙකක් ඇති බව පවසන්න: Aසහ B. Aඇත __init.py__. Bඇතුළත සිට යමක් ආයාත කිරීමට උත්සාහ කරන්න A.
msvalkon

36
init.pyහෝ __init__.pyගොනුවේ ඇතුළත ඇත්තේ කුමක්ද?
ලෝරම් ඉප්සම් ඩොලරය

50
@Xinyang එය හිස් ගොනුවක් විය හැකිය. එහි පැවැත්ම පයිතන්ට පවසන්නේ නාමාවලිය පැකේජයක් ලෙස සලකන ලෙසයි.
ජේ

9
ඇත්ත වශයෙන්ම මෙම පිළිතුර උපකල්පනය කර ඇති applicationඅතර එය appදැනටමත් පැකේජ වේ (එනම් ඔබ දැනටමත් මේ __init__.pyදෙකෙහිම ඇත). එකතු කිරීමේ ප්‍රති result ලයක් __init__.pyලෙස folder, application.app.folderඔබට (උප) පැකේජයක් බවට පත්වන අතර , එයින් ඔබට මොඩියුලයට ප්‍රවේශ විය හැකි අතර application.app.folder.file, එහි සංකේතය func_nameදැන් ආනයනය කළ හැකිය
යිබෝ යැං

32
මම කුමක් උත්සාහ කළත් මෙය සාර්ථක නොවනු ඇත. මට "සහෝදර සහෝදරියන්" නාමාවලියකින් ආනයනය කිරීමට අවශ්‍යයි, එබැවින් එකක් පහළට. සියල්ලන්ටම මව් ඇතුළු __ init __. පයි ඇත. මෙම පයිතන් 3 විශේෂිතද?
dasWesen

116

මොඩියුල සමාන්තර ස්ථානවල ඇති විට, ප්‍රශ්නය මෙන්:

application/app2/some_folder/some_file.py
application/app2/another_folder/another_file.py

මෙම කෙටිමං මඟින් එක් මොඩියුලයක් අනෙකට පෙනෙන පරිදි කරයි:

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

26
අවවාදයක් ලෙස: ආනයන ස්ක්‍රිප්ට් එහි අඩංගු නාමාවලියෙන් ක්‍රියාත්මක වන තාක් කල් මෙය ක්‍රියාත්මක වේ. එසේ නොමැතිනම් ස්ක්‍රිප්ට් ධාවනය වන වෙනත් ඕනෑම නාමාවලියක මව් නාමාවලිය මාර්ගයට එකතු වන අතර ආනයනය අසාර්ථක වනු ඇත.
කාල් ස්මිත්

14
එය වළක්වා ගැනීම සඳහා, අපට ගොනුවේ මව් නාමාවලිය ලබා ගත හැකියsys.path.append(os.path.dirname(os.path.abspath(__file__)))
රාහුල්

එය මට වැඩ කළේ නැත - දෙමව්පියන්ට නැවත නැගීමට මට එහි අමතර නාමයක් එක් කිරීමට සිදු විය, එවිට cli/foo.pyවිධාන රේඛාවෙන් ධාවනය වීමට හැකි වියimport cli.bar
RCross

2
Ah රාහුල්, ඔබේ විසඳුම අන්තර්ක්‍රියාකාරී ෂෙල් වෙඩි සඳහා ක්‍රියා නොකරයි
towi_parallelism

ඔබ එය ඔබගේ මූල ෆෝල්ඩරයෙන් (එනම් යෙදුම් ෆෝල්ඩරයෙන්) ධාවනය කරන්නේ sys.path.append('.')නම්, මොඩියුලය ආනයනය කිරීමෙන් ඔබ බොහෝ විට හොඳයි from app2.some_folder.some_file import your_function. විකල්පයක් ලෙස මට වැඩ කරන්නේ python3 -m app2.another_folder.another_fileroot ෆෝල්ඩරයෙන් ය.
ඇබ්බැහි වූ

77

පළමු වරට sys name-file.py වලින් ආයාත කරන්න

 import sys

දෙවනුව ෆෝල්ඩරයේ මාර්ගය name-file.py හි එකතු කරන්න

sys.path.insert(0, '/the/folder/path/name-package/')

තෙවනුව ඔබේ උප බහලුමේ __ init __.py නමින් හිස් ගොනුවක් සාදන්න (මෙය පයිතන්ට පවසන්නේ එය පැකේජයක් බවයි)

  • name-file.py
  • name-package
    • __ init __.py
    • name-module.py

හතරවනුව name-file.py හි ෆෝල්ඩරය තුළ මොඩියුලය ආයාත කරන්න

from name-package import name-module

6
නම-ෆෝල්ඩරය name-file.py ට පහළින් ඇති බැවින්, මෙය -කමාන්ඩ් නොමැතිව පවා ක්‍රියා කළ යුතුය sys.path.insert. නාම ෆෝල්ඩරය අත්තනෝමතික ස්ථානයක පිහිටා තිබියදීත් මෙම විසඳුම ක්‍රියාත්මක වන්නේ නම් පිළිතුර පිළිතුරෙන් ප්‍රශ්න කරයි.
බැස්ටියන්

58

ලේඛනයේ විස්තර කර ඇති පරිදි පාරිසරික විචල්‍යයPYTHONPATH භාවිතා කිරීම තාවකාලික ක්‍රමයක් වනු ඇතැයි මම සිතමි : පයිතන් 2 , පයිතන් 3

# Linux & OSX
export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH

# Windows
set PYTHONPATH=C:\path\to\dirWithScripts\;%PYTHONPATH%

ඉන්න, මම මගේ ස්ක්‍රිප්ට් ගොනු නාමයෙන් ප්‍රතිස්ථාපනය කරනවාද?
ව්ලැඩිමීර් පුටින්

4
නැත, ඔබේ .py ගොනුව වෙත නාමාවලියෙහි මාර්ගය සමඟ
Ax3l

2
අවාසනාවකට මෙන්, ඔබ ඇනකොන්ඩා භාවිතා කරන්නේ නම්, මෙය ක්‍රියා නොකරනු ඇත, මන්දයත් පයිතන්පාත් යටින් ඇත්ත වශයෙන්ම අභ්‍යන්තරව භාවිතා නොවන බැවිනි!
information_interchange

1
ඇනකොන්ඩා හි (මෑත) වෙනස්වීම් සඳහා, වැඩ ප්‍රවාහ සහ වැඩ කටයුතු සඳහා අදහස් දැක්වීම සඳහා මෙම SO බලන්න: stackoverflow.com/questions/17386880/… පොදුවේ ගත් කල, ආනයන ඩිරර් හැක් කිරීම වෙනුවට කුඩා පැකේජ තැනීම සහ ස්ථාපනය කිරීම.
Ax3l

49

මෙහි පිළිතුරු වල පැහැදිලි බවක් නොමැත, මෙය පයිතන් 3.6 හි පරීක්ෂා කෙරේ

මෙම ෆෝල්ඩර ව්‍යුහය සමඟ:

main.py
|
---- myfolder/myfile.py

myfile.pyඅන්තර්ගතය ඇත්තේ කොහේද :

def myfunc():
    print('hello')

ආනයන ප්‍රකාශය main.py:

from myfolder.myfile import myfunc
myfunc()

මෙය හෙලෝ මුද්‍රණය කරයි.


10
ක එකතු init myfolder මානකරන ගොනුව .py (හිස්) linux (y) මට වැඩ
වින්සන්ට්

8
In වින්සන්ට් ඔබ අදහස් කළේ __init__.py?
mrgloom

2
rmrgloom ඇත්ත වශයෙන්ම
වින්සන්ට්

3
කිසියම් හේතුවක් නිසා එකතු __init__.pyකිරීම මට ප්‍රයෝජනවත් නොවේ. මම උබුන්ටු 18 හි Py 3.6.5 භාවිතා කරමි. එය ක්‍රියා කරන්නේ Pycharm මත මිස පර්යන්තයෙන් නොවේ
Crearo Rotar

11
වර්තමාන වැඩ කරන නාමාවලියට වඩා ගොනු ගසෙහි වෙනත් ශාඛාවකින් ගොනු ආනයනය කිරීම පිළිබඳව අසන ප්‍රශ්නයට මෙය සම්පූර්ණයෙන්ම සම්බන්ධ නොවේ.
ඇලෙක්සැන්ඩර් රොසා

47

ඔබේ ගැටළුව වන්නේ පයිතන් මෙම ගොනුව සඳහා පයිතන් නාමාවලියෙහි සොයා බලා එය සොයා නොගැනීමයි. ඔබ කතා කරන්නේ ඔබ සිටින නාමාවලිය ගැන මිස පයිතන් ගැන නොවන බව සඳහන් කළ යුතුය.

මෙය සිදු කිරීම සඳහා ඔබ මෙය වෙනස් කරයි:

from application.app.folder.file import func_name

මේ සඳහා:

from .application.app.folder.file import func_name

තිත එකතු කිරීමෙන් ඔබ කියන්නේ පයිතන් නාමාවලිය දෙස බැලීම වෙනුවට යෙදුම් ෆෝල්ඩරය සඳහා මෙම ෆෝල්ඩරයේ බලන්න.


2
මෙය මා සවි කළේ
ෆි

32

මා දන්නා දෙයින්, __init__.pyඔබට ආනයනය කිරීමට අවශ්‍ය ශ්‍රිතයන්ගේ ෆෝල්ඩරයට කෙලින්ම ගොනුවක් එක් කරන්න .


7
වෙනත් ඩිරෙක්ටරියක් ඇතුළත් කිරීමට අවශ්‍ය ස්ක්‍රිප්ට් එක දැනටමත් sys.path හි තිබේ නම් පමණි
Ax3l

2
මම sys.path.append(tools_dir)වින්ඩෝස් හි භාවිතා කළ අතර මට __init__.py' file in my directory මෙවලම්_දිර එකතු කිරීමට අවශ්‍ය නැත
හර්ව්-ගුවෙරින්

27

පයිතන් 3.4 සහ පසුව, ඔබට ප්‍රභව ගොනුවකින් කෙලින්ම ආනයනය කළ හැකිය (ප්‍රලේඛනයට සබැඳිය) . මෙය සරලම විසඳුම නොවේ, නමුත් මම සම්පූර්ණත්වය සඳහා මෙම පිළිතුර ඇතුළත් කරමි.

මෙන්න උදාහරණයක්. පළමුව, ආනයනය කළ යුතු ගොනුව නම් කර ඇත foo.py:

def announce():
    print("Imported!")

ඉහත ගොනුව ආනයනය කරන කේතය, ප්‍රලේඛනයේ ඇති උදාහරණයෙන් බෙහෙවින් ආනුභාව ලත්:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()

ප්‍රතිදානය:

<module 'foo' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

විචල්ය නාමය, මොඩියුලයේ නම සහ ගොනු නාමය නොගැලපෙන බව සලකන්න. මෙම කේතය තවමත් ක්‍රියාත්මක වේ:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()

ප්‍රතිදානය:

<module 'bar' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

ක්‍රමයෙන් ආනයනය කරන මොඩියුලයන් පයිතන් 3.1 හි හඳුන්වා දී ඇති අතර මොඩියුල ආනයනය කරන ආකාරය පිළිබඳ වැඩි පාලනයක් ඔබට ලබා දෙයි. වැඩි විස්තර සඳහා ප්‍රලේඛනය වෙත යොමු වන්න.


12
කවුරුහරි මෙය තේරුම් ගැනීමට උත්සාහ කළාදැයි මම නොදනිමි, නමුත් එය ඉතා සංකීර්ණ යැයි මම සිතමි.
ඩෑන්

25

ලිනක්ස් හි python3 හි මා වෙනුවෙන් වැඩ කළා

import sys  
sys.path.append(pathToFolderContainingScripts)  
from scriptName import functionName #scriptName without .py extension  

8
sys.path.append("/home/linux/folder/")- කෙටිමඟක් භාවිතා නොකිරීමට වග බලා ගන්න උදා"~/folder/"
daGo

1
මෙය පහසුම පිළිතුරයි; වින්ඩෝස් සඳහාද ක්‍රියා කරයි.
ජෝන් ස්ටඩ්

22

පයිතන්ගේ සාපේක්ෂ ආනයන උත්සාහ කරන්න:

from ...app.folder.file import func_name

සෑම ප්‍රමුඛ තිතක්ම වත්මන් නාමාවලියෙන් ආරම්භ වන ධූරාවලියෙහි තවත් ඉහළ මට්ටමකි.


ගැටලු? මෙය ඔබ වෙනුවෙන් ක්‍රියා නොකරන්නේ නම්, බොහෝ ගොචාගේ සාපේක්ෂ ආනයන වලින් ඔබ ටිකක් අඩුවනු ඇත. වැඩි විස්තර සඳහා පිළිතුරු සහ අදහස් කියවන්න: __init__.py සමඟ වුවද "පැකේජ නොවන සාපේක්ෂ ආනයනය කිරීමට උත්සාහ කිරීම" නිවැරදි කරන්නේ කෙසේද?

ඉඟිය: __init__.pyසෑම නාමාවලි මට්ටමින්ම තිබිය යුතුය. ඔබට python -m application.app2.some_folder.some_fileඉහළ මට්ටමේ නාමාවලියෙන් ධාවනය වන (.py අතහැර දැමීම) හෝ ඔබේ PYTHONPATH හි ඉහළ මට්ටමේ නාමාවලිය තිබිය යුතුය. පියු!


22

මට එකම අභියෝගයකට මුහුණ දීමට සිදු විය, විශේෂයෙන් ගොනු කිහිපයක් ආනයනය කිරීමේදී, එය ජය ගැනීමට මට හැකි වූයේ එලෙසිනි.

import os, sys

from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))

from root_folder import file_name

2
සාමාන්‍ය ආනයනයකට වඩා වෙනස් වන්නේ කුමක්ද යන්න ඔබට පැහැදිලි කළ හැකි නම් ඔබ පිළිතුරු දීම වඩාත් ප්‍රයෝජනවත් වනු ඇත?
not2qubit

1
මට /path/dir1/__init__.py සහ /path/dir1/mod.py තිබුණා. Dir1.mod වෙතින් /path/some.py සඳහා ආනයනය කිරීමේ විනෝදය ක්‍රියාත්මක විය. /Path/dir2/some.py හි ඇති විට එය ක්‍රියාත්මක වූයේ මා ඉහත පිළිතුර ගොනුවේ ඉහළින් පිටපත් කර ඇලවීමෙන් පසුව පමණි. මා සතුව ඇති සෑම පයිතන් ව්‍යාපෘතියක්ම / path / හි නොමැති බැවින් මගේ මාර්ගය සංස්කරණය කිරීමට අවශ්‍ය නොවීය.
jwal

20

සලකා applicationඔබගේ පිඹුරා ව්යාපෘතිය සඳහා root බහලුම ලෙස, හිස් නිර්මාණය __init__.pyගොනුව application, appසහ folderෆෝල්ඩර. some_file.pyFunc_name හි අර්ථ දැක්වීම ලබා ගැනීම සඳහා ඔබ පහත පරිදි වෙනස්කම් සිදු කරන්න :

import sys
sys.path.insert(0, r'/from/root/directory/application')

from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file.
func_name()

විය යුත්තේ: sys.path.insert (0, r '/ from / root / directory')
බොලකා

18

යෙදුම වෙනත් පරිසරයන් වෙත ගෙන යන විට නිරපේක්ෂ මාර්ගයක් සමඟ sys.path.append භාවිතා කිරීම වඩාත් සුදුසු නොවේ. සාපේක්ෂ මාර්ගයක් භාවිතා කිරීම සැමවිටම ක්‍රියා නොකරන්නේ වර්තමාන වැඩ කරන නාමාවලිය ස්ක්‍රිප්ට් ආයාචනය කළ ආකාරය මත රඳා පවතින බැවිනි.

යෙදුම් ෆෝල්ඩරයේ ව්‍යුහය සවි කර ඇති බැවින්, අපට ආනයනය කිරීමට බලාපොරොත්තු වන මොඩියුලයේ සම්පූර්ණ මාර්ගය ලබා ගැනීමට අපට os.path භාවිතා කළ හැකිය. උදාහරණයක් ලෙස, මෙය ව්‍යුහය නම්:

/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py

ඔබට "අඹ" මොඩියුලය ආනයනය කිරීමට අවශ්ය යැයි කියමු. ඔබට පහත දැක්වෙන දේ vanilla.py හි කළ හැකිය:

import sys, os.path
mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+ '/another_folder/')
sys.path.append(mango_dir)
import mango

ඇත්ත වශයෙන්ම, ඔබට mango_dir විචල්‍යය අවශ්‍ය නොවේ.

මෙය ක්‍රියා කරන ආකාරය තේරුම් ගැනීමට මෙම අන්තර්ක්‍රියාකාරී සැසි උදාහරණය දෙස බලන්න:

>>> import os
>>> mydir = '/home/me/application/app2/some_folder'
>>> newdir = os.path.abspath(os.path.join(mydir, '..'))
>>> newdir
    '/home/me/application/app2'
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder'
>>> 
>>> newdir
'/home/me/application/app2/another_folder'
>>> 

Os.path ප්‍රලේඛනය පරීක්ෂා කරන්න .


13

මෙය මට කවුළු මත වැඩ කරයි

# some_file.py on mainApp/app2 
import sys
sys.path.insert(0, sys.path[0]+'\\app2')

import some_file

11

මම තරමක් විශේෂයි: මම වින්ඩෝස් සමඟ පයිතන් භාවිතා කරමි!

මම තොරතුරු සම්පුර්ණ කරමි: වින්ඩෝස් සහ ලිනක්ස් යන දෙකටම සාපේක්ෂ හා නිරපේක්ෂ මාවත ක්‍රියාත්මක වේ sys.path(මට පරිගණක කිහිපයක් සහ විවිධ ප්‍රධාන නාමාවලි යටතේ මගේ ස්ක්‍රිප්ට් භාවිතා කරන බැවින් මට සාපේක්ෂ මාර්ග අවශ්‍ය වේ).

වින්ඩෝස් දෙකම භාවිතා කරන විට \සහ /ගොනු නාම සඳහා බෙදුම්කරු ලෙස භාවිතා කළ හැකි අතර ඇත්ත වශයෙන්ම ඔබ \පයිතන් නූල් දෙගුණ කළ යුතුය ,
සමහර වලංගු උදාහරණ:

sys.path.append('c:\\tools\\mydir')
sys.path.append('..\\mytools')
sys.path.append('c:/tools/mydir')
sys.path.append('../mytools')

(සටහන: එය 'වින්ඩෝස්-ස්වදේශික' අඩු නම් එය /වඩා පහසු යැයි මම සිතමි \, මන්ද එය ලිනක්ස් අනුකූල වන අතර වින්ඩෝස් ගවේෂක වෙත ලිවීමට හා පිටපත් කිරීමට පහසුය)


4
os.path.join ('මෙවලම්', 'මයිඩර්')
කොරී ගෝල්ඩ්බර්ග්

10

මගේ නඩුවේදී මට ආනයනය කිරීමට පන්තියක් තිබුණි. මගේ ගොනුව මේ වගේ විය:

# /opt/path/to/code/log_helper.py
class LogHelper:
    # stuff here

මගේ ප්‍රධාන ගොනුවේ මම කේතය ඇතුළත් කළේ:

import sys
sys.path.append("/opt/path/to/code/")
from log_helper import LogHelper

1
in not2qubit sys පිළිතුරෙන් ආනයනය කර නැත.
වෝල්ටර්

7

විශේෂිත මාර්ගයකින් මොඩියුලයක් පැටවීමේ පරමාර්ථය අභිරුචි මොඩියුලයක් සංවර්ධනය කිරීමේදී ඔබට සහාය වීම නම්, ඔබට අභිරුචි මොඩියුලයේ මූලයට යොමු වන පරීක්ෂණ ස්ක්‍රිප්ටයේ එකම ෆෝල්ඩරයේම සංකේතාත්මක සබැඳියක් සෑදිය හැකිය. මෙම ෆෝල්ඩරයේ ක්‍රියාත්මක වන ඕනෑම ස්ක්‍රිප්ට් එකක් සඳහා එකම නමකින් ස්ථාපනය කර ඇති වෙනත් මොඩියුලවලට වඩා මෙම මොඩියුල යොමුව ප්‍රමුඛතාවය ගනී.

මම මෙය ලිනක්ස් හි පරීක්‍ෂා කළ නමුත් එය සංකේතාත්මක සබැඳි සඳහා සහාය දක්වන ඕනෑම නවීන මෙහෙයුම් පද්ධතියක ක්‍රියා කළ යුතුය.

මෙම ප්‍රවේශයේ ඇති එක් වාසියක් නම්, ඔබේම දේශීය SVC ශාඛා වැඩ පිටපතක වාඩි වී සිටින මොඩියුලයකට ඔබට යොමු කළ හැකි අතර එමඟින් සංවර්ධන චක්‍රයේ වේලාව බෙහෙවින් සරල කළ හැකි අතර මොඩියුලයේ විවිධ අනුවාදයන් කළමනාකරණය කිරීමේ අසාර්ථක ක්‍රම අඩු කළ හැකිය.


7

මම එකම ප්‍රශ්නයට කිහිප වතාවක්ම ගැසුවෙමි, එබැවින් මගේ විසඳුම බෙදා ගැනීමට කැමැත්තෙමි.

පයිතන් අනුවාදය: 3.X

පහත දැක්වෙන විසඳුම වන්නේ පයිතන් අනුවාදය 3.X හි ඔබේ යෙදුම සංවර්ධනය කරන අයෙකු සඳහා වන අතර පයිතන් 2 ජනවාරි / 1/2020 සිට සහාය නොදක්වයි .

ව්‍යාපෘති ව්‍යුහය

පයිතන් 3 හි, ව්‍යංග නාම__init__.py අවකාශ පැකේජ නිසා ඔබේ ව්‍යාපෘති උප බහලුම ඔබට අවශ්‍ය නොවේ . Python 3.3+ හි ඇති පැකේජ සඳහා Is init .py අවශ්‍ය නොවේ බලන්න

Project 
├── main.py
├── .gitignore
|
├── a
|   └── file_a.py
|
└── b
    └── file_b.py

ගැටළු ප්රකාශය

දී file_b.py, මම පන්ති ආනයනය කිරීමට කැමති Aඇති file_a.pyෆෝල්ඩරය යටතේ.

විසඳුම්

# 1 ඉක්මන් නමුත් අපිරිසිදු ක්‍රමයක්

ඔබ දැනට නව ව්‍යාපෘතියක් සංවර්ධනය කරමින් සිටින බැවින් පැකේජය ස්ථාපනය නොකර

try catchදෝෂ තිබේදැයි පරීක්ෂා කිරීමට භාවිතා කිරීම . කේත උදාහරණය:

import sys
try:
    # The insertion index should be 1 because index 0 is this file
    sys.path.insert(1, '/absolute/path/to/folder/a')  # the type of path is string
    # because the system path already have the absolute path to folder a
    # so it can recognize file_a.py while searching 
    from file_a import A
except (ModuleNotFoundError, ImportError) as e:
    print("{} fileure".format(type(e)))
else:
    print("Import succeeded")

# 2 ඔබේ පැකේජය ස්ථාපනය කරන්න

ඔබ ඔබේ යෙදුම ස්ථාපනය කළ පසු (මෙම ලිපියේ, ස්ථාපනයේ නිබන්ධනය ඇතුළත් නොවේ)

ඔබට සරලව කළ හැකිය

try:
    from __future__ import absolute_import
    # now it can reach class A of file_a.py in folder a 
    # by relative import
    from ..a.file_a import A  
except (ModuleNotFoundError, ImportError) as e:
    print("{} fileure".format(type(e)))
else:
    print("Import succeeded")

සුබ කේතීකරණයක්!



3

පහත දැක්වෙන ගොනු ලැයිස්තුව සමඟ aපරිශීලකයින්ට ස්ථාපනය කිරීමට අවශ්‍ය ව්‍යාපෘතියක මම වැඩ කරමින් සිටියෙමි pip install a:

.
├── setup.py
├── MANIFEST.in
└── a
    ├── __init__.py
    ├── a.py
    └── b
        ├── __init__.py
        └── b.py

setup.py

from setuptools import setup

setup (
  name='a',
  version='0.0.1',
  packages=['a'],
  package_data={
    'a': ['b/*'],
  },
)

MANIFEST.in

recursive-include b *.*

a / init .py

from __future__ import absolute_import

from a.a import cats
import a.b

a / a.py.

cats = 0

a / b / init .py

from __future__ import absolute_import

from a.b.b import dogs

a / b / b.py.

dogs = 1

මම මොඩියුලය ස්ථාපනය කළේ පහත සඳහන් නාමාවලියෙන් ධාවනය කිරීමෙන් ය MANIFEST.in:

python setup.py install

පසුව, මගේ ගොනු පද්ධතියේ සම්පූර්ණයෙන්ම වෙනස් ස්ථානයක සිට මට /moustache/armwrestleධාවනය කිරීමට හැකි විය:

import a
dir(a)

එමඟින් a.catsසත්‍ය වශයෙන්ම 0 ට සමාන වන අතර a.b.dogsඇත්ත වශයෙන්ම 1 ට සමාන වේ.


3

හුදෙක් දෙයක් කරනවා වෙනුවට import ...මෙය කරන්න:

from <MySubFolder> import <MyFile>

MyFile MySubFolder තුළ ඇත.


2

ෆෝල්ඩරයකින් මොඩියුලයක් ආනයනය කිරීමට අවශ්‍ය තැන මොඩියුල ආනයනය කිරීමට ඔබට importlib භාවිතා කළ හැකිය.

import importlib

scriptName = 'Snake'

script = importlib.import_module('Scripts\\.%s' % scriptName)

මෙම උදාහරණයේ main.py ඇති අතර එය ඉහත කේතය වන අතර පසුව ස්ක්‍රිප්ට්ස් නම් ෆෝල්ඩරයක් ඇති අතර scriptNameවිචල්‍යය වෙනස් කිරීමෙන් ඔබට මෙම ෆෝල්ඩරයෙන් ඔබට අවශ්‍ය ඕනෑම දෙයක් ඇමතිය හැකිය . එවිට ඔබට scriptමෙම මොඩියුලය වෙත යොමු වීමට භාවිතා කළ හැකිය . මට Hello()සර්ප මොඩියුලය තුළ ශ්‍රිතයක් තිබේ නම් ඔබට එසේ කිරීමෙන් මෙම ක්‍රියාව ක්‍රියාත්මක කළ හැකිය:

script.Hello()

මම මෙය පයිතන් 3.6 හි පරීක්ෂා කර ඇත්තෙමි


2

මට කිහිප වතාවක්ම මෙම ගැටළු ඇති වී තිබේ. මම මේ පිටුවට ගොඩක් ආවා. මගේ අන්තිම ගැටලුවේදී මට serverස්ථාවර ඩිරෙක්ටරියෙන් ධාවනය කිරීමට සිදු විය, නමුත් නිදොස් කිරීමේදී සෑම විටම විවිධ උප නාමාවලි වලින් ධාවනය කිරීමට මට අවශ්‍ය විය.

import sys
sys.insert(1, /path) 

නැත නොවේ මට වැඩ විවිධ මොඩියුල දී මම වෙනස් කියවීමට තිබූ නිසා * .csv එම බහලුම තුල සියලු තිබූ ගොනු.

අවසානයේදී, මා වෙනුවෙන් වැඩ කළේ පයිතොනික් නොවේ, මම අනුමාන කරමි, නමුත්:

මට නිදොස් කිරීමට අවශ්‍ය මොඩියුලයට ඉහළින් මම භාවිතා if __main__ කළෙමි , එය සාමාන්‍ය මාර්ගයට වඩා වෙනස් ආකාරයකින් ක්‍රියාත්මක වේ.

නිසා:

# On top of the module, instead of on the bottom
import os
if __name__ == '__main__':
    os.chdir('/path/for/the/regularly/run/directory')

1

ඔබට f5 එබීමෙන් පයිතන් කවචය නැවුම් කළ හැකිය, නැතහොත් Run-> Run Module වෙත යන්න. මේ ආකාරයෙන් ඔබට ගොනුවෙන් යමක් කියවීමට නාමාවලිය වෙනස් කිරීමට අවශ්‍ය නැත. පයිතන් ස්වයංක්‍රීයව නාමාවලිය වෙනස් කරයි. නමුත් ඔබට පයිතන් කවචයේ විවිධ නාමාවලි වලින් විවිධ ලිපිගොනු සමඟ වැඩ කිරීමට අවශ්‍ය නම් කැමරන් කලින් කී පරිදි ඔබට sys හි නාමාවලිය වෙනස් කළ හැකිය .


1

ඒ නිසා මම මගේ IDE මත දකුණු ක්ලික් කර, නව එකක් එකතු කර folderමට එයින් ආනයනය කිරීමට නොහැකි වූයේ මන්දැයි කල්පනා කරමින් සිටියෙමි. පසුව මට වැටහුණා මට රයිට් ක්ලික් කර පයිතන් පැකේජයක් සෑදිය යුතු බවත් එය සම්භාව්‍ය ගොනු පද්ධති ෆෝල්ඩරයක් නොවන බවත්. හෝ __init__.pyවෙනත් පිළිතුරුවල සඳහන් පරිදි පශ්චාත් මරණ පරීක්ෂණ ක්‍රමයක් (පයිතන් ගොනු පද්ධති ෆෝල්ඩරය පැකේජයක් ලෙස සලකයි) එකතු කිරීම . යමෙකු මෙම මාර්ගයට ගියහොත් මෙම පිළිතුර මෙහි එක් කිරීම.


1

මම සාමාන්‍යයෙන් මට ආනයනය කිරීමට අවශ්‍ය මොඩියුලයට සිම්ලින්ක් එකක් සාදමි. වත්මන් නාමාවලිය තුළ මොඩියුලය සොයා ගැනීමට පයිතන් පරිවර්තකයාට හැකි බව සිම්ලින්ක් මඟින් සහතික කරයි (ඔබ අනෙක් මොඩියුලය ආනයනය කරන ස්ක්‍රිප්ට්); පසුව ඔබගේ වැඩ අවසන් වූ පසු, ඔබට සිම් ලින්ක් ඉවත් කළ හැකිය. එසේම, .gitignore හි ඇති සිම්ලින්ක් නොසලකා හැරිය යුතුය, එවිට ඔබ අහම්බෙන් ඔබේ සම්බන්ධතාවයට සමමුහුර්ත මොඩියුලයන් සිදු නොකරනු ඇත. මෙම ප්‍රවේශය මඟින් ඔබ ක්‍රියාත්මක කරන ස්ක්‍රිප්ටයට සමාන්තරව පිහිටා ඇති මොඩියුල සමඟ සාර්ථකව වැඩ කිරීමට ඉඩ ලබා දේ.

ln -s ~/path/to/original/module/my_module ~/symlink/inside/the/destination/directory/my_module

1

පැකේජයක් නිර්මාණය කිරීම සඳහා ඇති හොඳම පුහුණුව main_module.pyඉහළම මට්ටමේ නාමාවලිය වැනි මොඩියුලයකින් අනෙක් මොඩියුලයන් ධාවනය කර ප්‍රවේශ විය හැකිය .

ඉහළ මට්ටමේ නාමාවලි ගොනුවක් භාවිතා කිරීමෙන් ඔබට උප පැකේජය, මව් පැකේජය හෝ එකම මට්ටමේ පැකේජ සහ මොඩියුල භාවිතා කළ හැකි බව මෙම ව්‍යුහය පෙන්නුම් කරයි main_module.py.

පරීක්ෂා කිරීම සඳහා මෙම ලිපිගොනු සහ ෆෝල්ඩර සාදන්න සහ ක්‍රියාත්මක කරන්න:

 package
    |
    |----- __init__.py (Empty file)
    |------- main_module.py (Contains: import subpackage_1.module_1)        
    |------- module_0.py (Contains: print('module_0 in parent directory, is imported'))
    |           
    |
    |------- subpackage_1/
    |           |
    |           |----- __init__.py (Empty file)
    |           |----- module_1.py (Contains: print('importing other modules from module_1...')
    |           |                             import module_0
    |           |                             import subpackage_2.module_2
    |           |                             import subpackage_1.sub_subpackage_3.module_3)
    |           |----- photo.png
    |           |
    |           |
    |           |----- sub_subpackage_3/
    |                        |
    |                        |----- __init__.py (Empty file)
    |                        |----- module_3.py (Contains: print('module_3 in sub directory, is imported')) 
    |
    |------- subpackage_2/
    |           |
    |           |----- __init__.py (Empty file)
    |           |----- module_2.py (Contains: print('module_2 in same level directory, is imported'))

දැන් දුවන්න main_module.py

ප්‍රතිදානය වේ

>>>'importing other modules from module_1...'
   'module_0 in parent directory, is imported'
   'module_2 in same level directory, is imported'
   'module_3 in sub directory, is imported'

පින්තූර සහ ලිපිගොනු විවෘත කිරීම සටහන:

පැකේජ ව්‍යුහයක් තුළ ඔබට ඡායාරූපයකට ප්‍රවේශ වීමට අවශ්‍ය නම්, ඉහළම මට්ටමේ නාමාවලියෙන් නිරපේක්ෂ නාමාවලිය භාවිතා කරන්න.

අපි දුවමු, ඔබට ඇතුළත module_0.pyවිවෘත කිරීමට අවශ්‍ය යැයි සිතමු .photo.pngmodule_1.py

දේ module_1.pyඅඩංගු විය යුතුය වේ:

නිවැරදි:

image_path = 'subpackage_1/photo.png'
cv2.imread(image_path)

වැරදි:

image_path = 'photo.png'
cv2.imread(image_path)

නමුත් module_1.pyසහ photo.pngඑම බහලුම වේ.


0

ඔබට බහු ෆෝල්ඩර සහ උප ෆෝල්ඩර තිබේ නම්, ඔබට සෑම විටම ප්‍රධාන නාමාවලියෙන් ඕනෑම පන්තියක් හෝ මොඩියුලයක් ආනයනය කළ හැකිය .

උදාහරණයක් ලෙස: ව්‍යාපෘතියේ ගස් ව්‍යුහය

Project 
├── main.py
├── .gitignore
|
├── src
     ├────model
     |    └── user_model.py
     |────controller
          └── user_controller.py

දැන්, main.py ගොනුවේ user_model.py වෙතින් "UserModel" පන්තිය ආනයනය කිරීමට ඔබට අවශ්‍ය නම් , ඔබට එය භාවිතා කළ හැකිය:

from src.model.user_model.py import UserModel

එසේම, ඔබට එකම රේඛාවක් භාවිතා කර user_controller.py ගොනුවේ එකම පන්තියක් ආයාත කළ හැකිය :

from src.model.user_model.py import UserModel

සමස්තයක් ලෙස ගත් විට, ඔබ තුළ කිසිදු පිඹුරා ගොනුව ආනයන පන්ති සහ ගොනු කිරීමට ප්රධාන ව්යාපෘතිය බහලුම සමුද්දේශ දිය හැකි ව්යාපෘති බහලුම.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.