සම්පූර්ණ මාර්ගය අනුව මොඩියුලයක් ආනයනය කරන්නේ කෙසේද?


1178

පයිතන් මොඩියුලයක් එහි සම්පූර්ණ මාර්ගය අනුව පටවන්නේ කෙසේද? වින්‍යාස විකල්පයක් බැවින් ගොනුව ගොනු පද්ධතියේ ඕනෑම තැනක තිබිය හැකි බව සලකන්න.


37
ලස්සන සහ සරල ප්රශ්නයට - හා ප්රයෝජනවත් පිළිතුරු නමුත් ඔවුන් මට පිඹුරා මන්ත්රය වන්නේ 'නැත සමග සිදුවූයේ කුමක්ද යන්න කරන්න එක් පැහැදිලි එය කිරීමට ක්රමයක් ".. එය තනි හෝ එය සරල හා පැහැදිලි පිළිතුරක් වගේ දෙයක් වගේ බවක් පෙනෙන්නට නැත. .
inger

1
“එය කිරීමට එක් පැහැදිලි ක්‍රමයක් තිබේ” යන පයිතන් මන්ත්‍රයෙන් සිදු වූ දේ [...] [තනි] හෝ එයට සරල හා පැහැදිලි පිළිතුරක් නොවේ [...] හාස්‍යජනක ලෙස අනවසරයෙන් [...] වඩාත් පිපිරී ඇත නවතම අනුවාද වල පිඹුරා පැකේජ කළමනාකරණ පිළිබඳ දරුණු ලෝක ඔබ සාදරයෙන් පිළිගනිමු. Python මීට උදාහරණ ගේ import, virtualenv, pip, setuptoolswhatnot සියලු එළියට තල්ලූ සහ කම්කරු කේතය සමඟ ආදේශ කල හැක. මම අදහසත් මට උත්සාහ virtualenvහෝ එය විය pipenvහා ජම්බෝ ජෙට් අත්පොත කට සමාන ගන්නා මාර්ගය වැඩ කිරීමට සිදු විය. නියෝජිතයින් සමඟ ගනුදෙනු කිරීමේ විසඳුම ලෙස එම උපක්‍රමය පෙළපාළි යන ආකාරය මුළුමනින්ම මග හැරේ.
ජෝන් ෆ්‍රේසර්

Answers:


1318

පයිතන් 3.5+ භාවිතය සඳහා:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

පයිතන් 3.3 සහ 3.4 භාවිතය සඳහා:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(මෙය පයිතන් 3.4 හි ඉවත් කර ඇතත්.)

පයිතන් 2 භාවිතය සඳහා:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

සම්පාදනය කරන ලද පයිතන් ලිපිගොනු සහ ඩීඑල්එල් සඳහා සමාන පහසුවක් ඇත.

Http://bugs.python.org/issue21436 ද බලන්න .


55
මම නම් අවකාශය දැන සිටියේ නම් - 'module.name' - මම දැනටමත් භාවිතා කරමි __import__.
ශ්‍රීධර් රත්නකුමාර්

63
Rid ශ්‍රිධර් රත්නකුමාර් පළමු තර්කයේ වටිනාකම ආපසු ලබා දුන් මොඩියුලයේ imp.load_sourceකට්ටල පමණක් සකසයි .__name__. එය පැටවීමට බලපාන්නේ නැත.
ඩෑන් ඩී.

17
An ඩෑන්. - පළමු තර්කය ශබ්ද කෝෂයේ imp.load_source()නිර්මාණය කරන ලද නව ප්‍රවේශයේ යතුර තීරණය කරයි sys.modules, එබැවින් පළමු තර්කය පැටවීමට බලපායි.
බ්‍රැන්ඩන් රෝඩ්ස්

9
මෙම impමෙම: මොඩියුලය අනුවාදය 3.4 සිට ප්රතික්ෂේප කරයි impපක්ෂව පැකේජය විභාග වෙමින් පවතී deprecation importlib.
චියෙල් ටෙන් බ්‍රින්කේ

9
තරමට @AXO සහ තවත් එක් අරුමපුදුම දේ සරල සහ මූලික ලෙස යමක් ඇයි මේ ලෙස ඇති නිසා සංකීර්ණ කළ යුතුය. එය වෙනත් බොහෝ භාෂාවල නොමැත.
පාෂාණ

433

Sys.path වෙත මාර්ගයක් එක් කිරීමේ වාසිය (imp භාවිතා කිරීම ඉක්මවා), එය එක් පැකේජයකින් එක් මොඩියුලයකට වඩා ආනයනය කිරීමේදී දේවල් සරල කරයි. උදාහරණයක් වශයෙන්:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch

14
sys.path.appendඩිරෙක්ටරියක් වෙනුවට තනි පයිතන් ගොනුවකට යොමු කිරීමට අප භාවිතා කරන්නේ කෙසේද ?
Phani

29
:-) සමහර විට ඔබේ ප්‍රශ්නය StackOverflow ප්‍රශ්නයක් ලෙස වඩාත් සුදුසු වනු ඇත, පිළිතුරක් පිළිබඳ අදහස් දැක්වීමක් නොවේ.
ඩැරල් ස්පිට්සර්

3
පයිතන් මාර්ගයට සිප් ලේඛනාගාර, “බිත්තර” (සංකීර්ණ ආකාරයේ සිප් ලේඛනාගාර) යනාදිය අඩංගු විය හැකිය. මොඩියුල ඒවායින් ආනයනය කළ හැකිය. එබැවින් මාර්ග මූලද්‍රව්‍ය ඇත්ත වශයෙන්ම ලිපිගොනු බහාලුම් වේ, නමුත් ඒවා අනිවාර්යයෙන්ම නාමාවලි නොවේ.
ඇලෙක්සිස්

12
පයිතන් ආනයන ප්‍රකාශ හැඹිලි වලින් පරිස්සම් වන්න. ඔබට එක් පන්තියේ නමක් (පන්තිඑක්ස්) බෙදා ගන්නා විවිධ ෆෝල්ඩර දෙකක් ඇති දුර්ලභ අවස්ථාවෙහිදී, sys.path වෙත මාර්ගයක් එක් කිරීම, පංතිය X ආනයනය කිරීම, මාර්ගය ඉවත් කිරීම සහ නැවත යථා තත්ත්වයට පත් කිරීමේ මාර්ග සඳහා පුනරාවර්තනය කිරීමේ ප්‍රවේශය ක්‍රියාත්මක නොවේ. පයිතන් සෑම විටම පන්තිය එහි හැඹිලියෙන් පළමු මාර්ගයෙන් පටවනු ඇත. මගේ නඩුවේදී මම අරමුණු කළේ සියලුම ප්ලගීන විශේෂිත පන්ති X ක්‍රියාත්මක කරන ප්ලගීන පද්ධතියක් නිර්මාණය කිරීමයි. මම SourceFileLoader භාවිතා කිරීම අවසන් කළෙමි , එහි ක්ෂය කිරීම මතභේදාත්මක බව සලකන්න .
ComFreek

3
මෙම ප්‍රවේශය මඟින් ආනයනය කරන ලද මොඩියුලයට එකම මොඩියුලයකින් ආනයනය කිරීමට ඉඩ ලබා දෙන අතර මොඩියුල බොහෝ විට සිදු කරයි, පිළිගත් පිළිතුරේ ප්‍රවේශය (අවම වශයෙන් 3.7 මත) සිදු නොවේ. importlib.import_module(mod_name)ක්‍රියාකාරී වේලාවේදී මොඩියුලයේ නම නොදන්නේ නම් මෙහි ඇති පැහැදිලි ආනයනය වෙනුවට භාවිතා කළ හැකිය sys.path.pop(). කෙසේ වෙතත්, ආනයනික කේතය භාවිතා කරන විට වැඩි මොඩියුල ආනයනය කිරීමට උත්සාහ නොකරනු ඇතැයි උපකල්පනය කරමි.
එලී_බී

51

ඔබේ ඉහළ මට්ටමේ මොඩියුලය ගොනුවක් නොවන නමුත් __init__.py සමඟ නාමාවලියක් ලෙස ඇසුරුම් කර තිබේ නම්, පිළිගත් විසඳුම බොහෝ දුරට ක්‍රියාත්මක වේ, නමුත් එතරම් නොවේ. පයිතන් 3.5+ හි පහත කේතය අවශ්‍ය වේ ('sys.modules' සමඟ ආරම්භ වන එකතු කළ රේඛාව සටහන් කරන්න):

MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module 
spec.loader.exec_module(module)

මෙම රේඛාව නොමැතිව, exec_module ක්‍රියාත්මක කරන විට, එය ඔබගේ ඉහළ මට්ටමේ සාපේක්ෂ ආනයන __init__.py ඉහළ මට්ටමේ මොඩියුලයේ නමට බැඳීමට උත්සාහ කරයි - මේ අවස්ථාවේ දී “mymodule”. නමුත් "mymodule" තවම පටවා නැති නිසා ඔබට දෝෂය ලැබෙනු ඇත "SystemError: දෙමාපිය මොඩියුලය 'mymodule' පටවා නැත, සාපේක්ෂ ආනයනය කළ නොහැක". එබැවින් ඔබ එය පූරණය කිරීමට පෙර නම බැඳ තැබිය යුතුය. එයට හේතුව සාපේක්ෂ ආනයන පද්ධතියේ මූලික වෙනස්කමයි: “වෙනස් නොවන රඳවා ගැනීම නම් ඔබට sys.modules ['spam'] සහ sys.modules ['spam.foo'] තිබේ නම් (ඉහත ආනයනයෙන් පසුව ඔබ කැමති පරිදි) ), දෙවැන්න මෙහි සාකච්ඡා කර ඇති පරිදි කලින් සඳහන් කළ මෝඩ ගුණාංගය ලෙස දිස්විය යුතුය .


1
ගොඩක් ස්තුතියි! මෙම ක්‍රමය මඟින් උප මොඩියුල අතර සාපේක්ෂ ආනයන සක්‍රීය කරයි. මහා!
tebanep

මෙම පිළිතුර මෙහි ඇති ප්‍රලේඛනයට ගැලපේ : docs.python.org/3/library/… .
ටිම් ලුඩ්වින්ස්කි

1
නමුත් කුමක්ද mymodule?
ගුල්සාර්

Ul ගුල්සාර්, ඔබේ මොඩියුලය ලබා දීමට ඔබ කැමති ඕනෑම නමක් වන අතර පසුව ඔබට එය කළ හැකිය: "mymodule import myclass වෙතින්"
Idodo

ඉතින් ... /path/to/your/module/ඇත්ත වශයෙන්ම /path/to/your/PACKAGE/? සහ mymoduleඔබ අදහස් කළේ myfile.py?
ගුල්සාර්

40

ඔබේ මොඩියුලය ආයාත කිරීම සඳහා, ඔබ එහි නාමාවලිය තාවකාලිකව හෝ ස්ථිරවම පරිසර විචල්‍යයට එක් කළ යුතුය.

තාවකාලිකව

import sys
sys.path.append("/path/to/my/modules/")
import my_module

ස්ථිරවම

ඔබගේ .bashrcගොනුවට (ලිනක්ස් වලින්) පහත පේළිය එකතු කර source ~/.bashrcපර්යන්තය තුළ ක්‍රියාත්මක කරන්න:

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

ණය / මූලාශ්‍රය: saarrrr , තවත් කොටස් හුවමාරු ප්‍රශ්නයක්


3
වෙනත් තැනක ජුපිටර් නෝට්බුක් එකක ව්‍යාපෘතියක් කිරීමට ඔබට අවශ්‍ය නම් මෙම “තාවකාලික” විසඳුම හොඳ පිළිතුරකි.
fordy

නමුත් ... එය මාර්ගය
අවුල්

HaShaiAlon ඔබ මාර්ග එකතු කරමින් සිටින අතර, ඔබ එක් පරිගණකයකින් තවත් පරිගණකයකට කේත මාරු කරන විට හැර වෙනත් අනතුරක් නැත, මාර්ග අවුල් විය හැක. එබැවින්, පැකේජ සංවර්ධනය සඳහා, මම ආනයනය කරන්නේ දේශීය පැකේජ පමණි. එසේම, පැකේජ නාම අද්විතීය විය යුතුය. ඔබ කනස්සල්ලට පත්ව සිටී නම්, තාවකාලික විසඳුම භාවිතා කරන්න.
මිලාඩියස්

31

වින්‍යාස ගොනුව විශේෂයෙන් ආනයනය කිරීමට ඔබට අවශ්‍ය නැති බව පෙනේ (එයට අතුරු ආබාධ සහ අමතර සංකූලතා රාශියක් ඇත), ඔබට එය ක්‍රියාත්මක කිරීමට අවශ්‍ය වන අතර එහි ප්‍රති name ලයක් ලෙස ඇති නාම අවකාශයට ප්‍රවේශ විය හැකිය. සම්මත පුස්තකාලය ඒ සඳහා විශේෂයෙන් runpy.run_path ස්වරූපයෙන් API සපයයි :

from runpy import run_path
settings = run_path("/path/to/file.py")

එම අතුරුමුහුණත පයිතන් 2.7 සහ පයිතන් 3.2+ වලින් ලබා ගත හැකිය


මම මෙම ක්‍රමයට කැමතියි, නමුත් run_path හි ප්‍රති result ලය ලබා ගත් විට එහි ශබ්දකෝෂය මට ප්‍රවේශ විය නොහැකි බව පෙනේ?
ස්ටීවන් එල්වුඩ්

"ප්‍රවේශ විය නොහැක" යන්නෙන් ඔබ අදහස් කරන්නේ කුමක්ද? ඔබ එය ආනයනය (මෙම ආනයන ආකාරයේ ප්රවේශ ඇත්තටම අවශ්ය නොවේ විට පමණක් හොඳ විකල්පය වන්නේ ඇයි බව,) බැහැ, නමුත් අන්තර්ගතය නිත්ය dict API හරහා ලබා ගත හැකි විය යුතුය ( result[name], result.get('name', default_value), ආදී)
ncoghlan

මෙම පිළිතුර අවතක්සේරු කර ඇත. එය ඉතා කෙටි හා සරලයි! ඊටත් වඩා හොඳයි, ඔබට නිසි මොඩියුල නාම අවකාශයක් අවශ්‍ය නම්, ඔබට එවැනි දෙයක් කළ හැකිය from runpy import run_path; from argparse import Namespace; mod = Namespace(**run_path('path/to/file.py'))
RuRo

20

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

අවුල් සහගත නමුත් එය ක්‍රියාත්මක වේ.

configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config

එය ගතික නොවේ.
ෂයි ඇලොන්

මම උත්සාහ කළෙමි: config_file = 'chat-for chats', setup_file = get_setup_file (config_file + ".py"), sys.path.append (os.path.dirname (os.path.expanduser (setup_file)), ආනයන config_file >> "ImportError: config_file නමින් මොඩියුලයක් නොමැත"
ෂායි ඇලොන්

17

ඔබට භාවිතා කළ හැකිය

load_source(module_name, path_to_file) 

imp මොඩියුලයේ ක්‍රමය .


... සහ imp.load_dynamic(module_name, path_to_file)ඩීඑල්එල් සඳහා
හෙක්ටෝ

34
දැන් එම අගය ඉවත් කර ඇත.
t1m0

14

ඔබ අදහස් කරන්නේ පැටවීම හෝ ආනයනය කිරීමද?

ඔබට sys.pathලැයිස්තුව හැසිරවිය හැකි අතර ඔබේ මොඩියුලයට මාර්ගය නියම කරන්න, ඉන්පසු ඔබේ මොඩියුලය ආයාත කරන්න. උදාහරණයක් ලෙස, මොඩියුලයක් ලබා දී ඇත්තේ:

/foo/bar.py

ඔබට කළ හැකිය:

import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar

1
HeWheat ඇයි sys.path [0] වෙනුවට sys.path [0: 0]?
user618677

5
B / c sys.path [0] = xy පළමු මාර්ග අයිතමය නැවත ලියන අතර මාර්ගය [0: 0] = xy යනු path.insert (0, xy) ට සමාන වේ
dom0

2
hm the path.insert මා වෙනුවෙන් වැඩ කළ නමුත් [0: 0] උපක්‍රමය සාර්ථක නොවීය.
jsh


7
Explicit is better than implicit.ඉතින් ඒ sys.path.insert(0, ...)වෙනුවට නොවන්නේ ඇයි sys.path[0:0]?
winklerrr

13
def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except:
        raise ImportError

import_file('/home/somebody/somemodule.py')

38
සම්මත පුස්තකාලය විසින් දැනටමත් ආමන්ත්‍රණය කර ඇති විට දෝෂ සහිත පේළි 14 ක් ලිවිය යුත්තේ ඇයි? ඔබ සම්පූර්ණ_පාත්_ට_මොඩියුලයේ ආකෘතිය හෝ අන්තර්ගතය පිළිබඳ දෝෂ පරීක්‍ෂා කර නැත. අල්ලා ගැනීම-සියල්ල භාවිතා කිරීමexcept: වගන්තියක් භාවිතා කිරීම කලාතුරකින් හොඳ අදහසකි.
ක්‍රිස් ජොන්සන්

ඔබ මෙහි තවත් "උත්සාහ-අවසාන" භාවිතා කළ යුතුය. උදාsave_cwd = os.getcwd() try: … finally: os.chdir(save_cwd)
කේ - එස්ඊ නපුරු ය

11
H ක්‍රිස් ජොන්සන් this is already addressed by the standard libraryඔව්, නමුත් පයිතන්ට පසුගාමී- නොගැලපීමේ නරක පුරුද්දක් ඇත ... පරීක්ෂා කළ පිළිතුර පවසන පරිදි 3.3 ට පෙර සහ පසු විවිධ ක්‍රම 2 ක් ඇත. එවැනි අවස්ථාවක මම පියාසර කරන චෙක් අනුවාදයට වඩා මගේම විශ්වීය ශ්‍රිතයක් ලිවීමට කැමතියි. ඔව්, සමහර විට මෙම කේතය එතරම් දෝෂ සහිත නොවන නමුත් එය අදහසක් පෙන්වයි (එය os.chdir (), මම ඒ ගැන එසේ කර නැත), මට වඩා හොඳ කේතයක් ලිවිය හැකි පදනම මත. එබැවින් +1.
සුෂි 271

මෙය ඇත්ත වශයෙන්ම මොඩියුලය ආපසු ලබා දුන්නේ නම් එය සිසිල් වනු ඇත.
පිටිකෝස්

13

2.7-3.5 සිට බොහෝ පයිතන් අනුවාද වල ක්‍රියා කරන කේත කිහිපයක් මෙන්න.

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())

මම එය පරීක්ෂා කළා. එය කැත විය හැකි නමුත් මෙතෙක් සියලුම අනුවාද වල ක්‍රියාත්මක වන්නේ එකම එකකි.


1
මෙම පිළිතුර මට වැඩ load_sourceකළේ එය ස්ක්‍රිප්ට් ආනයනය කරන නිසා සහ ආනයනය කරන අවස්ථාවේ දී මොඩියුල සහ ග්ලෝබල් වෙත ස්ක්‍රිප්ට් ප්‍රවේශය සපයන බැවිනි.
ක්ලික්

13

මම තරමක් වෙනස් කළ අනුවාදයක් ඉදිරිපත් කර ඇත්තෙමි @ සෙබස්තියන් රිටාවෝගේ අපූරු පිළිතුර (පයිතන්> 3.4 සඳහා), spec_from_loaderඒ වෙනුවට මොඩියුලයක් ලෙස ඕනෑම දිගුවක් සහිත ගොනුවක් පැටවීමට ඔබට ඉඩ සලසයි spec_from_file_location:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

මාර්ගය පැහැදිලි ලෙස කේතනය කිරීමේ වාසිය SourceFileLoaderනම් යන්ත්‍රය දිගුවේ සිට ගොනුවේ වර්ගය සොයා ගැනීමට උත්සාහ නොකරනු ඇත. මෙහි අරුත වන්නේ, ඔබ විසින් වගේ දෙයක් පූරණය කළ හැකි මාධ්යයක් .txtමෙම ක්රමය භාවිතයෙන්,, නමුත් ඔබට එය කරන්න බැරි spec_from_file_locationනිසා කාරකය නියම තොරව .txtනොවන importlib.machinery.SOURCE_SUFFIXES.


8

නිශ්චිත මොඩියුලය භාවිතා කිරීමට imp.find_module()සහ imp.load_module()පැටවීමට ඔබට හැකි යැයි මම විශ්වාස කරමි . ඔබට මොඩියුලයේ නම මාර්ගයෙන් වෙන් කිරීමට අවශ්‍ය වනු ඇත, එනම් ඔබට පැටවීමට අවශ්‍ය නම් ඔබ /home/mypath/mymodule.pyකළ යුත්තේ:

imp.find_module('mymodule', '/home/mypath/')

... නමුත් එම කාර්යය ඉටු කළ යුතුයි.


7

අපට එකම ව්‍යාපෘතියක ස්ක්‍රිප්ට් තිබේ නම් නමුත් විවිධ ඩිරෙක්ටරි ක්‍රම වලින් අපට පහත සඳහන් ක්‍රමවේදය මඟින් මෙම ගැටළුව විසඳා ගත හැකිය.

මෙම තත්වය utils.pyතුළsrc/main/util/

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

import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method

1
සරලම එක IMO
Ardhi

6

වත්මන් නාමාවලියෙහි ඇති පැකේජ ලැයිස්තුවක් ලබා ගැනීමට ඔබට pkgutilමොඩියුලය (විශේෂයෙන් walk_packagesක්‍රමය) භාවිතා කළ හැකිය . එතැන් සිට importlibඔබට අවශ්‍ය මොඩියුල ආනයනය කිරීම සඳහා යන්ත්‍ර සූත්‍ර භාවිතා කිරීම සුළුපටු ය :

import pkgutil
import importlib

packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
    mod = importlib.import_module(name)
    # do whatever you want with module now, it's been imported!

5

පයිතන් මොඩියුලය test.py සාදන්න

import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3

Python මොඩියුලය සාදන්න test_check.py

from test import Client1
from test import Client2
from test import test3

අපට ආනයනික මොඩියුලය මොඩියුලයෙන් ආනයනය කළ හැකිය.


4

පයිතන් 3.4 හි මෙම ප්‍රදේශය තේරුම් ගැනීමට අතිශයින්ම කරදරකාරී බව පෙනේ! කෙසේ වෙතත් ආරම්භයක් ලෙස ක්‍රිස් කැලෝවේගේ කේතය භාවිතා කරමින් සුළු වශයෙන් අනවසරයෙන් ඇතුළුවීම නිසා මට යමක් වැඩ කිරීමට හැකි විය. මෙන්න මූලික කාර්යය.

def import_module_from_file(full_path_to_module):
    """
    Import a module given the full path/filename of the .py file

    Python 3.4

    """

    module = None

    try:

        # Get module name and path from full path
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)

        # Get module "spec" from filename
        spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)

        module = spec.loader.load_module()

    except Exception as ec:
        # Simple error printing
        # Insert "sophisticated" stuff here
        print(ec)

    finally:
        return module

මෙය පයිතන් 3.4 වෙතින් ඉවත් නොකළ මොඩියුල භාවිතා කරන බව පෙනේ. එයට හේතුව තේරුම් ගැනීමට මම රඟපාන්නේ නැත, නමුත් එය වැඩ සටහනක් තුළ සිට ක්‍රියාත්මක වන බව පෙනේ. ක්‍රිස්ගේ විසඳුම විධාන රේඛාවේ වැඩ කරන බව මට පෙනී ගියේය.


4

එය වඩා හොඳ යැයි මම නොකියමි, නමුත් සම්පූර්ණත්වය සඳහා, execපයිතන් 2 සහ 3 යන දෙකින්ම ලබා ගත හැකි ශ්‍රිතය යෝජනා කිරීමට මට අවශ්‍ය විය . exec , ගෝලීය විෂය පථයෙන් හෝ අභ්‍යන්තර විෂය පථයකින් අත්තනෝමතික කේත ක්‍රියාත්මක කිරීමට ඔබට ඉඩ සලසයි. ශබ්ද කෝෂයක් ලෙස සපයා ඇත.

උදාහරණයක් ලෙස, ඔබට "/path/to/moduleශ්‍රිතය සමඟ මොඩියුලයක් ගබඩා කර ඇත්නම් foo(), පහත සඳහන් දෑ කිරීමෙන් ඔබට එය ක්‍රියාත්මක කළ හැකිය:

module = dict()
with open("/path/to/module") as f:
    exec(f.read(), module)
module['foo']()

මෙය ඔබ කේතය ගතිකව පටවන බව මඳක් පැහැදිලිව පෙනෙන අතර අභිරුචි බිල්ඩින් සැපයීමේ හැකියාව වැනි අමතර බලයක් ඔබට ලබා දෙයි.

යතුරු වෙනුවට ගුණාංග හරහා ප්‍රවේශ වීම ඔබට වැදගත් නම්, ඔබට එවැනි ප්‍රවේශයක් සපයන ගෝලීයයන් සඳහා අභිරුචි ඩික්ට් පංතියක් සැලසුම් කළ හැකිය, උදා:

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)

4

දී ඇති ගොනු නාමයකින් මොඩියුලයක් ආයාත කිරීම සඳහා, ඔබට තාවකාලිකව මාර්ගය දීර් extend කළ හැකි අතර, අවසාන වශයෙන් වාරණ යොමුව තුළ පද්ධති මාර්ගය යථා තත්වයට පත් කළ හැකිය :

filename = "directory/module.py"

directory, module_name = os.path.split(filename)
module_name = os.path.splitext(module_name)[0]

path = list(sys.path)
sys.path.insert(0, directory)
try:
    module = __import__(module_name)
finally:
    sys.path[:] = path # restore

3

මෙය ක්‍රියාත්මක විය යුතුය

path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
    basename = os.path.basename(infile)
    basename_without_extension = basename[:-3]

    # http://docs.python.org/library/imp.html?highlight=imp#module-imp
    imp.load_source(basename_without_extension, infile)

4
දිගුව කපා හැරීමට වඩාත් පොදු ක්‍රමයක් නම් : name, ext = os.path.splitext(os.path.basename(infile)). ඔබගේ ක්‍රමය ක්‍රියාත්මක වන්නේ .py දිගුව සඳහා පෙර තිබූ සීමාව නිසාය. එසේම, ඔබ බොහෝ විට මොඩියුලය යම් විචල්‍ය / ශබ්ද කෝෂ ප්‍රවේශයකට ආනයනය කළ යුතුය.
ReneSac

3

මේ සඳහා විශේෂයෙන් කැප වූ පැකේජයක් තිබේ:

from thesmuggler import smuggle

# À la `import weapons`
weapons = smuggle('weapons.py')

# À la `from contraband import drugs, alcohol`
drugs, alcohol = smuggle('drugs', 'alcohol', source='contraband.py')

# À la `from contraband import drugs as dope, alcohol as booze`
dope, booze = smuggle('drugs', 'alcohol', source='contraband.py')

එය පයිතන් අනුවාදයන් හරහා පරීක්ෂා කර ඇත (ජයිතන් සහ පයිපී ද), නමුත් එය ඔබේ ව්‍යාපෘතියේ ප්‍රමාණය අනුව අධික ලෙස මරා දැමිය හැකිය.


2

මම impඔබ වෙනුවෙන් භාවිතා කරන පැකේජයක් සෑදුවා . මම එය අමතන අතර එය import_fileභාවිතා කරන්නේ එලෙසයි:

>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')

ඔබට එය ලබා ගත හැකිය:

http://pypi.python.org/pypi/import_file

හෝ දී

http://code.google.com/p/import-file/


1
os.chdir? (අදහස් දැක්වීම අනුමත කිරීමට අවම අක්ෂර).
ychaouche

මම මුළු දවසම ගත කළේ පයින්ස්ටලර් ජනනය කරන ලද exe එකක ආනයන දෝෂයකි. අවසානයේ මෙය මට වැඩ කළ එකම දෙයයි. මෙය සෑදීම ගැන ඔබට බොහෝම ස්තූතියි!
frakman1

2

ධාවන වේලාවේදී පැකේජ මොඩියුල ආයාත කරන්න (පයිතන් වට්ටෝරුව)

http://code.activestate.com/recipes/223972/

###################
##                #
## classloader.py #
##                #
###################

import sys, types

def _get_mod(modulePath):
    try:
        aMod = sys.modules[modulePath]
        if not isinstance(aMod, types.ModuleType):
            raise KeyError
    except KeyError:
        # The last [''] is very important!
        aMod = __import__(modulePath, globals(), locals(), [''])
        sys.modules[modulePath] = aMod
    return aMod

def _get_func(fullFuncName):
    """Retrieve a function object from a full dotted-package name."""

    # Parse out the path, module, and function
    lastDot = fullFuncName.rfind(u".")
    funcName = fullFuncName[lastDot + 1:]
    modPath = fullFuncName[:lastDot]

    aMod = _get_mod(modPath)
    aFunc = getattr(aMod, funcName)

    # Assert that the function is a *callable* attribute.
    assert callable(aFunc), u"%s is not callable." % fullFuncName

    # Return a reference to the function itself,
    # not the results of the function.
    return aFunc

def _get_class(fullClassName, parentClass=None):
    """Load a module and retrieve a class (NOT an instance).

    If the parentClass is supplied, className must be of parentClass
    or a subclass of parentClass (or None is returned).
    """
    aClass = _get_func(fullClassName)

    # Assert that the class is a subclass of parentClass.
    if parentClass is not None:
        if not issubclass(aClass, parentClass):
            raise TypeError(u"%s is not a subclass of %s" %
                            (fullClassName, parentClass))

    # Return a reference to the class itself, not an instantiated object.
    return aClass


######################
##       Usage      ##
######################

class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass

def storage_object(aFullClassName, allOptions={}):
    aStoreClass = _get_class(aFullClassName, StorageManager)
    return aStoreClass(allOptions)

2

ලිනක්ස් හි, ඔබේ පයිතන් ස්ක්‍රිප්ට් පිහිටා ඇති නාමාවලියෙහි සංකේතාත්මක සබැඳියක් එක් කිරීම ක්‍රියා කරයි.

එනම්:

ln -s /absolute/path/to/module/module.py /absolute/path/to/script/module.py

python නිර්මාණය කරන /absolute/path/to/script/module.pycඅතර ඔබ අන්තර්ගතය වෙනස් කළහොත් එය යාවත්කාලීන කරනු ඇත/absolute/path/to/module/module.py

ඉන්පසු mypythonscript.py හි පහත සඳහන් දෑ ඇතුළත් කරන්න

from module import *

1
මෙය මා භාවිතා කළ කඩුල්ල වන අතර, එය මට යම් යම් ගැටලු ඇති කර තිබේ. වඩාත් වේදනාකාරී එකක් නම්, IDEA හට සබැඳිය තුළ සිට වෙනස් කළ කේතයක් ලබා නොගන්නා ගැටළුවක් ඇති නමුත් එය එහි ඇතැයි සිතන දේ සුරැකීමට උත්සාහ කිරීමයි. අවසන් වරට ඉතිරි කර ගත හැකි ධාවන තත්වයක් වන්නේ ... මට මේ නිසා හොඳ වැඩ ප්‍රමාණයක් අහිමි විය.
ග්‍රිප්

I ඔබේ ගැටලුව මට වැටහී ඇත්දැයි ග්‍රිප්ට විශ්වාස නැත, නමුත් මම නිතරම (සම්පූර්ණයෙන්ම පාහේ) මගේ ඩෙස්ක්ටොප් එකේ සිට දුරස්ථ සේවාදායකයක සිට SFTP හරහා සයිබර් ඩක් වැනි සේවාදායකයකු සමඟ මගේ ස්ක්‍රිප්ට් සංස්කරණය කරමි, එවැනි අවස්ථාවකදී උත්සාහ කිරීම නරක අදහසකි සමමුහුර්ත ගොනුව සංස්කරණය කරන්න, ඒ වෙනුවට මුල් ගොනුව සංස්කරණය කිරීම වඩා ආරක්ෂිත වේ. ස්ක්‍රිප්ටයේ ඔබ විසින් සිදුකරන ලද වෙනස්කම් ඇත්ත වශයෙන්ම එය ප්‍රභව ලේඛනයට යොමු කරන බවත් ඊතර් නැති නොවී ඇති බවත් තහවුරු කර ගැනීම සඳහා ඔබ භාවිතා කිරීමෙන් gitසහ පරීක්ෂා කිරීමෙන් ඔබට මෙම ගැටළු වලින් සමහරක් අල්ලා ගත හැකිය git status.
user5359531

2

importlibමොඩියුලය මත පදනම්ව මම මගේම ගෝලීය සහ අතේ ගෙන යා හැකි ආනයන ශ්‍රිතයක් ලියා ඇත:

  • මොඩියුලය දෙකම උප මොඩියුලයක් ලෙස ආනයනය කිරීමට සහ මොඩියුලයක අන්තර්ගතය මව් මොඩියුලයකට ආනයනය කිරීමට (හෝ මව් මොඩියුලයක් නොමැති නම් ගෝලීයයකට).
  • ගොනු නාමයක කාල අක්‍ෂර සහිත මොඩියුල ආයාත කිරීමට හැකි වීම.
  • ඕනෑම දිගුවක් සමඟ මොඩියුල ආනයනය කිරීමට හැකි වීම.
  • පෙරනිමියෙන් දිගුවක් නොමැතිව ගොනු නාමයක් වෙනුවට උප මොඩියුලයක් සඳහා ස්වාධීන නමක් භාවිතා කිරීමට හැකි වීම.
  • පෙර ආනයනය කරන ලද මොඩියුලය මත පදනම්ව ආනයන ඇණවුම නිර්වචනය කිරීමට හැකි වනු ඇත sys.path.

උදාහරණ නාමාවලි ව්‍යුහය:

<root>
 |
 +- test.py
 |
 +- testlib.py
 |
 +- /std1
 |   |
 |   +- testlib.std1.py
 |
 +- /std2
 |   |
 |   +- testlib.std2.py
 |
 +- /std3
     |
     +- testlib.std3.py

ඇතුළත් කිරීමේ යැපීම සහ පිළිවෙල:

test.py
  -> testlib.py
    -> testlib.std1.py
      -> testlib.std2.py
    -> testlib.std3.py 

ක්‍රියාත්මක කිරීම:

නවතම වෙනස්කම් ගබඩාව: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py

test.py :

import os, sys, inspect, copy

SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("test::SOURCE_FILE: ", SOURCE_FILE)

# portable import to the global space
sys.path.append(TACKLELIB_ROOT) # TACKLELIB_ROOT - path to the library directory
import tacklelib as tkl

tkl.tkl_init(tkl)

# cleanup
del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
sys.path.pop()

tkl_import_module(SOURCE_DIR, 'testlib.py')

print(globals().keys())

testlib.base_test()
testlib.testlib_std1.std1_test()
testlib.testlib_std1.testlib_std2.std2_test()
#testlib.testlib.std3.std3_test()                             # does not reachable directly ...
getattr(globals()['testlib'], 'testlib.std3').std3_test()     # ... but reachable through the `globals` + `getattr`

tkl_import_module(SOURCE_DIR, 'testlib.py', '.')

print(globals().keys())

base_test()
testlib_std1.std1_test()
testlib_std1.testlib_std2.std2_test()
#testlib.std3.std3_test()                                     # does not reachable directly ...
globals()['testlib.std3'].std3_test()                         # ... but reachable through the `globals` + `getattr`

testlib.py :

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("1 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std1', 'testlib.std1.py', 'testlib_std1')

# SOURCE_DIR is restored here
print("2 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std3', 'testlib.std3.py')

print("3 testlib::SOURCE_FILE: ", SOURCE_FILE)

def base_test():
  print('base_test')

testlib.std1.py :

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std1::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/../std2', 'testlib.std2.py', 'testlib_std2')

def std1_test():
  print('std1_test')

testlib.std2.py :

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std2::SOURCE_FILE: ", SOURCE_FILE)

def std2_test():
  print('std2_test')

testlib.std3.py :

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std3::SOURCE_FILE: ", SOURCE_FILE)

def std3_test():
  print('std3_test')

ප්‍රතිදානය ( 3.7.4):

test::SOURCE_FILE:  <root>/test01/test.py
import : <root>/test01/testlib.py as testlib -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib'])
base_test
std1_test
std2_test
std3_test
import : <root>/test01/testlib.py as . -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib', 'testlib_std1', 'testlib.std3', 'base_test'])
base_test
std1_test
std2_test
std3_test

Python පරීක්ෂා 3.7.4, 3.2.5,2.7.16

වාසි :

  • මොඩියුලය දෙකම උප මොඩියුලයක් ලෙස ආනයනය කළ හැකි අතර මොඩියුලයක අන්තර්ගතය මව් මොඩියුලයකට ආනයනය කළ හැකිය (නැතහොත් මව් මොඩියුලයක් නොමැති නම් ගෝලීයව).
  • ගොනු නාමයකින් කාල පරිච්ඡේද සහිත මොඩියුල ආයාත කළ හැකිය.
  • ඕනෑම දිගු මොඩියුලයකින් ඕනෑම දිගු මොඩියුලයක් ආයාත කළ හැකිය.
  • (උදාහරණයක් ලෙස, දීර්ඝ තොරව වෙනුවට ගොනු නාමය ක submodule සඳහා නවීන නාමයක් භාවිතා කළ හැක පෙරනිමියෙන් වන testlib.std.pyලෙස testlib, testlib.blabla.pyලෙසtestlib_blabla හා එසේ මත).
  • A මත රඳා නොපවතී sys.path හෝ සෙවුම් මාර්ග ගබඩාවක් .
  • ඇමතුම් වැනි SOURCE_FILEසහ SOURCE_DIRඅතර ගෝලීය විචල්‍යයන් සුරැකීමට / ප්‍රතිස්ථාපනය කිරීමට අවශ්‍ය නොවේtkl_import_module .
  • [සඳහා 3.4.xසහ ඊට වැඩි] මොඩියුලයේ නාම අවකාශයන් කැදැලි tkl_import_moduleඇමතුම් වල මිශ්‍ර කළ හැකිය (උදා: named->local->namedහෝlocal->named->local එසේ ය).
  • [සඳහා 3.4.xසහ ඊට වැඩි] tkl_import_module( tkl_declare_globalශ්‍රිතය හරහා ) ආනයනය කරන ලද සියලුම ළමා මොඩියුල වෙත ප්‍රකාශයට පත් කරන ලද ගෝලීය විචල්‍යයන් / කාර්යයන් / පන්ති ස්වයංක්‍රීයව අපනයනය කළ හැකිද?

අවාසි :

  • [සඳහා 3.3.xසහ පහළ] (කේත අනුපිටපත්) tkl_import_moduleකැඳවන සියලුම මොඩියුලවල ප්‍රකාශ කිරීමට අවශ්‍ය වේtkl_import_module

1,2 යාවත්කාලීන කරන්න (සඳහා3.4.x සහ ඊට වැඩි):

පයිතන් 3.4 සහ ඊට වැඩි tkl_import_moduleසෑම ප්‍රකාශයකින්ම එක් එක් මොඩියුලයේ ප්‍රකාශ කිරීමේ අවශ්‍යතාවය මඟ හැරිය හැකtkl_import_moduleඉහළ මට්ටමේ මොඩියුලයකින් අතර, එම ක්‍රියාව මඟින් සියලුම ළමුන්ගේ මොඩියුලයන් එකම ඇමතුමකින් එන්නත් කරනු ඇත (එය එක්තරා ආකාරයක ස්වයං යෙදවුම් ආනයනයකි).

යාවත්කාලීන 3 :

ආනයනය කිරීමේදී ආධාරක ක්‍රියාත්මක කිරීමේ ආරක්ෂකයා සමඟ tkl_source_moduleඇනලොග් ලෙස ඇනලොග් ලෙස එකතු කරන ලදි source(ආනයනය වෙනුවට මොඩියුලය ඒකාබද්ධ කිරීම හරහා ක්‍රියාත්මක වේ).

යාවත්කාලීන 4 :

tkl_declare_globalළමා මොඩියුලයක කොටසක් නොවන නිසා මොඩියුලය ගෝලීය විචල්‍යයක් නොපෙනෙන සියලුම ළමා මොඩියුල සඳහා මොඩියුලයක් ගෝලීය විචල්‍යයක් ස්වයංක්‍රීයව අපනයනය කිරීම සඳහා එකතු කරන ලදි .

යාවත්කාලීන 5 :

සියලුම කාර්යයන් ටැක්ලිබ් පුස්තකාලයට මාරු වී ඇත, ඉහත සබැඳිය බලන්න.


1

මට වැඩ කරන කිසිවක් සොයාගත නොහැකි වූ නිසා මෙය පිළිතුරු ලැයිස්තුවට එක් කිරීම. 3.4 හි සම්පාදනය කරන ලද (පයිඩ්) පයිතන් මොඩියුල ආනයනය කිරීමට මෙය ඉඩ දෙයි:

import sys
import importlib.machinery

def load_module(name, filename):
    # If the Loader finds the module name in this list it will use
    # module_name.__file__ instead so we need to delete it here
    if name in sys.modules:
        del sys.modules[name]
    loader = importlib.machinery.ExtensionFileLoader(name, filename)
    module = loader.load_module()
    locals()[name] = module
    globals()[name] = module

load_module('something', r'C:\Path\To\something.pyd')
something.do_something()

1

තරමක් සරල ක්‍රමයක්: ඔබට සාපේක්ෂ මාර්ගය සමඟ ගොනුව ආයාත කිරීමට අවශ්‍ය යැයි සිතමු ../../MyLibs/pyfunc.py


libPath = '../../MyLibs'
import sys
if not libPath in sys.path: sys.path.append(libPath)
import pyfunc as pf

නමුත් ඔබ එය ආරක්ෂකයෙකු නොමැතිව කළහොත් ඔබට අවසානයේ ඉතා දිගු මාර්ගයක් ලබා ගත හැකිය


1

පැකේජය importlibවෙනුවට භාවිතා කරන සරල විසඳුමක් imp(පයිතන් 2.7 සඳහා පරීක්ෂා කර ඇත, නමුත් එය පයිතන් 3 සඳහාද ක්‍රියා කළ යුතුය):

import importlib

dirname, basename = os.path.split(pyfilepath) # pyfilepath: '/my/path/mymodule.py'
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # '/my/path/mymodule.py' --> 'mymodule'
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")

දැන් ඔබට ආනයනික මොඩියුලයේ නාම අවකාශය කෙලින්ම භාවිතා කළ හැකිය:

a = module.myvar
b = module.myfunc(a)

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


මේ ආකාරයට ඔබ වෙනස් කරන sys.pathඅතර එය සෑම භාවිත අවස්ථාවකටම නොගැලපේ.
bgusach

gbgusach මෙය සත්‍ය විය හැකි නමුත් සමහර අවස්ථාවලදීද එය යෝග්‍ය වේ (sys.path වෙත මාර්ගයක් එක් කිරීම එක් පැකේජයකින් එක් මොඩියුලයකට වඩා ආනයනය කිරීමේදී දේවල් සරල කරයි). කෙසේ වෙතත්, මෙය සුදුසු නොවේ නම්, කෙනෙකුට වහාම කළ හැකියsys.path.pop()
අටැක්සියස්

0

මෙම පිළිතුර සෙබස්තියන් රිටාවුගේ පිළිතුරට අතිරේකයකි: "නමුත් ඔබට මොඩියුලයේ නම නොමැති නම් කුමක් කළ යුතුද?" මෙය ගොනුවේ නමක් ලබා දී ඇති පයිතන් මොඩියුලයේ නම ලබා ගැනීමේ ඉක්මන් හා අපිරිසිදු ක්‍රමයකි - එය __init__.pyගොනුවක් නොමැතිව නාමාවලියක් සොයාගෙන එය නැවත ගොනු නාමයක් බවට පත් කරන තෙක් එය ගස උඩට යයි . Python 3.4+ සඳහා (pathlib භාවිතා කරයි), Py2 පුද්ගලයන්ට "imp" හෝ සාපේක්ෂ ආනයන සිදු කළ හැකි වෙනත් ක්‍රම භාවිතා කළ හැකි බැවින් එය අර්ථවත් කරයි:

import pathlib

def likely_python_module(filename):
    '''
    Given a filename or Path, return the "likely" python module name.  That is, iterate
    the parent directories until it doesn't contain an __init__.py file.

    :rtype: str
    '''
    p = pathlib.Path(filename).resolve()
    paths = []
    if p.name != '__init__.py':
        paths.append(p.stem)
    while True:
        p = p.parent
        if not p:
            break
        if not p.is_dir():
            break

        inits = [f for f in p.iterdir() if f.name == '__init__.py']
        if not inits:
            break

        paths.append(p.stem)

    return '.'.join(reversed(paths))

වැඩිදියුණු කිරීම සඳහා නිසැකවම හැකියාවන් ඇති අතර, විකල්ප __init__.pyලිපිගොනු වෙනත් වෙනස්කම් අවශ්‍ය විය හැකිය, නමුත් ඔබට __init__.pyපොදුවේ තිබේ නම්, මෙය උපක්‍රමය කරයි.


-1

හොඳම ක්‍රමය, නිල ලියකියවිලි වලින් ( 29.1 imp. - ආනයන අභ්‍යන්තරයට ප්‍රවේශ වන්න ):

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()

1
මෙම විසඳුම මඟින් මාර්ගය සැපයීමට ඔබට ඉඩ නොදේ, ප්‍රශ්නය අසන්නේ එයයි.
මීකා ස්මිත්
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.