[英]How do I import other Python files?
如何在 Python 中導入文件? 我要導入:
file.py
)不要匆忙選擇第一個適合您的導入策略,否則當您發現它不滿足您的需求時,您將不得不重寫代碼庫。
我將開始解釋最簡單的示例#1,然后我將轉向最專業和最強大的示例#7
示例 1,使用 python 解釋器導入 python 模塊:
把它放在 /home/el/foo/fox.py 中:
def what_does_the_fox_say(): print("vixens cry")
進入python解釋器:
el@apollo:/home/el/foo$ python Python 2.7.3 (default, Sep 26 2013, 20:03:06) >>> import fox >>> fox.what_does_the_fox_say() vixens cry >>>
您通過 python 解釋器導入了 fox,從 fox.py 中調用了 python 函數what_does_the_fox_say()
。
示例 2,在腳本中使用execfile
或( Python 3 中的exec
)來執行其他 python 文件:
把它放在 /home/el/foo2/mylib.py 中:
def moobar(): print("hi")
把它放在 /home/el/foo2/main.py 中:
execfile("/home/el/foo2/mylib.py") moobar()
運行文件:
el@apollo:/home/el/foo$ python main.py hi
moobar 函數是從 mylib.py 導入的,並在 main.py 中可用
示例 3,使用 from ... import ... 功能:
把它放在 /home/el/foo3/chekov.py 中:
def question(): print "where are the nuclear wessels?"
把它放在 /home/el/foo3/main.py 中:
from chekov import question question()
像這樣運行它:
el@apollo:/home/el/foo3$ python main.py where are the nuclear wessels?
如果您在 chekov.py 中定義了其他函數,除非您import *
,否則它們將不可用
示例 4,如果 riaa.py 與導入位置不同,則導入 riaa.py
把它放在 /home/el/foo4/stuff/riaa.py 中:
def watchout(): print "computers are transforming into a noose and a yoke for humans"
把它放在 /home/el/foo4/main.py 中:
import sys import os sys.path.append(os.path.abspath("/home/el/foo4/stuff")) from riaa import * watchout()
運行:
el@apollo:/home/el/foo4$ python main.py computers are transforming into a noose and a yoke for humans
這會從不同的目錄導入外部文件中的所有內容。
示例 5,使用os.system("python yourfile.py")
import os
os.system("python yourfile.py")
示例 6,通過搭載 python startuphook 導入文件:
更新:這個例子曾經適用於 python2 和 3,但現在只適用於 python2。 python3 擺脫了這個用戶啟動鈎子功能集,因為它被低技能的 Python 庫編寫者濫用,在所有用戶定義的程序之前使用它來不禮貌地將他們的代碼注入全局命名空間。 如果你想讓它適用於 python3,你將不得不變得更有創意。 如果我告訴你怎么做,python 開發人員也會禁用該功能集,所以你只能靠自己了。
請參閱: https ://docs.python.org/2/library/user.html
將此代碼放入您的主目錄~/.pythonrc.py
class secretclass:
def secretmessage(cls, myarg):
return myarg + " is if.. up in the sky, the sky"
secretmessage = classmethod( secretmessage )
def skycake(cls):
return "cookie and sky pie people can't go up and "
skycake = classmethod( skycake )
將此代碼放入您的 main.py 中(可以在任何地方):
import user
msg = "The only way skycake tates good"
msg = user.secretclass.secretmessage(msg)
msg += user.secretclass.skycake()
print(msg + " have the sky pie! SKYCAKE!")
運行它,你應該得到這個:
$ python main.py
The only way skycake tates good is if.. up in the sky,
the skycookie and sky pie people can't go up and have the sky pie!
SKYCAKE!
如果您在此處收到錯誤: ModuleNotFoundError: No module named 'user'
那么這意味着您正在使用 python3,startuphooks 在默認情況下被禁用。
這個 jist 的功勞歸功於: https ://github.com/docwhat/homedir-examples/blob/master/python-commandline/.pythonrc.py 沿着你的船發送。
示例 7,最強大:使用裸導入命令在 python 中導入文件:
/home/el/foo5/
/home/el/foo5/herp
在 herp 下創建一個名為__init__.py
的空文件:
el@apollo:/home/el/foo5/herp$ touch __init__.py el@apollo:/home/el/foo5/herp$ ls __init__.py
創建一個新目錄 /home/el/foo5/herp/derp
在 derp 下,創建另一個__init__.py
文件:
el@apollo:/home/el/foo5/herp/derp$ touch __init__.py el@apollo:/home/el/foo5/herp/derp$ ls __init__.py
在 /home/el/foo5/herp/derp 下新建一個名為yolo.py
的文件,把它放在那里:
def skycake(): print "SkyCake evolves to stay just beyond the cognitive reach of " + "the bulk of men. SKYCAKE!!"
關鍵時刻,制作新文件/home/el/foo5/main.py
,把它放在那里;
from herp.derp.yolo import skycake skycake()
運行:
el@apollo:/home/el/foo5$ python main.py SkyCake evolves to stay just beyond the cognitive reach of the bulk of men. SKYCAKE!!
空的__init__.py
文件與 Python 解釋器通信,開發人員希望該目錄成為可導入的包。
如果您想查看我關於如何在目錄下包含所有 .py 文件的帖子,請參見此處: https ://stackoverflow.com/a/20753073/445131
importlib
被添加到 Python 3 以編程方式導入模塊。
import importlib
moduleName = input('Enter module name:')
importlib.import_module(moduleName)
應該從moduleName
中刪除 .py 擴展名。 該函數還為相對導入定義了一個package
參數。
在 python 2.x 中:
import file
__init__.py
文件,可以將文件夾標記為包__import__
函數,它將模塊名稱(不帶擴展名)作為字符串擴展名pmName = input('Enter module name:')
pm = __import__(pmName)
print(dir(pm))
鍵入help(__import__)
以獲取更多詳細信息。
第一個案例
您想在文件A.py
中導入文件B.py
,這兩個文件在同一個文件夾中,如下所示:
.
├── A.py
└── B.py
您可以在文件B.py
中執行此操作:
import A
或者
from A import *
或者
from A import THINGS_YOU_WANT_TO_IMPORT_IN_A
然后你就可以在文件A.py
中使用文件B.py
的所有功能了
第二種情況
您要在文件 B.py 中導入文件folder/A.py
B.py
這兩個文件不在同一個文件夾中,如下所示:
.
├── B.py
└── folder
└── A.py
您可以在文件B.py
中執行此操作:
import folder.A
或者
from folder.A import *
或者
from folder.A import THINGS_YOU_WANT_TO_IMPORT_IN_A
然后你就可以在文件A.py
中使用文件B.py
的所有功能了
概括
A.py
是您在文件B.py
中導入的模塊,您使用了語法import module_name
。folder
是包含模塊A.py
的包,您使用了語法import package_name.module_name
。有關包和模塊的更多信息,請參閱此鏈接。
要在“運行時”導入具有已知名稱的特定 Python 文件:
import os
import sys
...
scriptpath = "../Test/"
# Add the directory containing your module to the Python path (wants absolute paths)
sys.path.append(os.path.abspath(scriptpath))
# Do the import
import MyModule
您沒有很多復雜的方法可以將 python 文件從一個文件夾導入到另一個文件夾。 只需創建一個__init__.py文件來聲明此文件夾是一個 python 包,然后轉到您要導入的主機文件,只需鍵入
from root.parent.folder.file import variable, class, whatever
導入文檔 .. -- 參考鏈接
需要__init__.py
文件才能使 Python 將目錄視為包含包,這樣做是為了防止具有通用名稱(例如字符串)的目錄無意中隱藏模塊搜索路徑中稍后出現的有效模塊。
__init__.py
可以只是一個空文件,但它也可以執行包的初始化代碼或設置__all__
變量。
mydir/spam/__init__.py
mydir/spam/module.py
import spam.module
or
from spam import module
from file import function_name ######## Importing specific function
function_name() ######## Calling function
和
import file ######## Importing whole package
file.function1_name() ######## Calling function
file.function2_name() ######## Calling function
這是我現在理解的兩種簡單方法,並確保要作為庫導入的“file.py”文件僅存在於當前目錄中。
如果定義的函數在文件x.py
:
def greet():
print('Hello! How are you?')
在要導入函數的文件中,寫下:
from x import greet
如果您不想導入文件中的所有函數,這很有用。
導入 .py 文件的最佳方式是通過__init__.py
。 最簡單的做法是在 your.py 文件所在的同一目錄中創建一個名為__init__.py
的空文件。
Mike Grouchy 的這篇文章很好地解釋了__init__.py
及其用於制作、導入和設置 python 包的用途。
我想在別處添加我不太清楚的注釋; 在模塊/包中,從文件加載時,模塊/包名稱必須以mymodule
為前綴。 想象一下mymodule
的布局是這樣的:
/main.py
/mymodule
/__init__.py
/somefile.py
/otherstuff.py
從__init__.py
加載somefile.py
/ otherstuff.py
時,內容應如下所示:
from mymodule.somefile import somefunc
from mymodule.otherstuff import otherfunc
使用 Python 3.5 或更高版本,您可以使用importlib.util
直接將任意位置的.py
文件作為模塊導入,而無需修改sys.path
。
import importlib.util
import sys
def load_module(file_name, module_name)
spec = importlib.util.spec_from_file_location(module_name, file_name)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
return module
file_name
參數必須是字符串或類似路徑的對象。 module_name
參數是必需的,因為所有加載的 Python 模塊都必須有一個(帶點的)模塊名稱(如sys
、 importlib
或importlib.util
),但您可以為這個新模塊選擇任何可用的名稱。
你可以像這樣使用這個函數:
my_module = load_module("file.py", "mymod")
在使用load_module()
函數將其導入 Python 進程一次后,該模塊將可以使用給定的模塊名稱導入。
# file.py =
print(f"{__name__} imported (file.py)")
# =========
# one.py ==
print(f"{__name__} imported (one.py)")
load_module("file.py", "mymod")
import two
# =========
# two.py ==
print(f"{__name__} imported (two.py)")
import mymod
# =========
鑒於上述文件,您可以運行以下命令來查看file.py
是如何變得可導入的。
$ python3 -m one
__main__ imported (one.py)
two imported (two.py)
mymod imported (file.py)
此答案基於官方 Python 文檔: importlib
: Importing a source file directly。
import sys
#print(sys.path)
sys.path.append('../input/tokenization')
import tokenization
要導入任何 .py 文件,您可以使用上面的代碼。
先追加路徑再導入
注意:'../input/tokenization'目錄包含tokenization.py文件
我如何導入是導入文件並使用它的名稱的簡寫。
import DoStuff.py as DS
DS.main()
不要忘記您的導入文件必須以 .py 擴展名命名
有幾種方法可以包含名稱為 abc.py 的 python 腳本
導入 abc
從文件夾導入 abc
從文件夾.internal_folder 導入 abc
導入操作系統
導入系統
腳本路徑 = "../Test/MyModule.py"
sys.path.append(os.path.abspath(scriptpath))
導入我的模塊
如果您的 python 腳本得到更新並且您不想上傳 - 使用這些語句進行自動刷新。 獎金 :)
%load_ext autoreload
%autoreload 2
如果您要導入的模塊不在子目錄中,請嘗試以下操作並從最深的公共父目錄運行app.py
:
目錄結構:
/path/to/common_dir/module/file.py
/path/to/common_dir/application/app.py
/path/to/common_dir/application/subpath/config.json
在app.py
中,將客戶端的路徑附加到 sys.path:
import os, sys, inspect
sys.path.append(os.getcwd())
from module.file import MyClass
instance = MyClass()
可選(如果您加載例如配置)(檢查似乎是我的用例中最強大的)
# Get dirname from inspect module
filename = inspect.getframeinfo(inspect.currentframe()).filename
dirname = os.path.dirname(os.path.abspath(filename))
MY_CONFIG = os.path.join(dirname, "subpath/config.json")
跑
user@host:/path/to/common_dir$ python3 application/app.py
該解決方案在 cli 和 PyCharm 中都適用於我。
這就是我從 python 文件中調用函數的方式,這對我來說可以靈活地調用任何函數。
import os, importlib, sys
def callfunc(myfile, myfunc, *args):
pathname, filename = os.path.split(myfile)
sys.path.append(os.path.abspath(pathname))
modname = os.path.splitext(filename)[0]
mymod = importlib.import_module(modname)
result = getattr(mymod, myfunc)(*args)
return result
result = callfunc("pathto/myfile.py", "myfunc", arg1, arg2)
只是將python文件導入另一個python文件
假設我有helper.py python 文件,它具有顯示功能,例如,
def display():
print("I'm working sundar gsv")
現在在app.py中,你可以使用顯示功能,
import helper
helper.display()
輸出,
I'm working sundar gsv
注意:無需指定 .py 擴展名。
你也可以這樣做: from filename import something
示例: from client import Client
請注意,您不需要.py .pyw .pyui
擴展名。
這聽起來可能很瘋狂,但如果您只是為其創建一個包裝腳本,則可以創建一個指向要導入的文件的符號鏈接。
Python 的一個非常不為人知的特性是能夠導入zip
文件:
library.zip
|-library
|--__init__.py
包的__init__.py
文件包含以下內容:
def dummy():
print 'Testing things out...'
我們可以編寫另一個腳本,它可以從 zip 存檔中導入一個包。 只需將 zip 文件添加到 sys.path。
import sys
sys.path.append(r'library.zip')
import library
def run():
library.dummy()
run()
這有助於我使用Visual Studio Code構建我的 Python 項目。
當您沒有在目錄中聲明__init__.py
時,可能會導致問題。 並且該目錄成為implicit namespace package
。 這是關於Python 導入和項目結構的一個很好的總結。
此外,如果您想使用 Visual Studio Code 運行按鈕 在帶有不在主包內的腳本的頂部欄中,您可以嘗試從實際目錄運行控制台。
例如,您想從測試包中執行一個打開的test_game_item.py
,並且您在omission
(主包)目錄中打開了 Visual Studio Code:
├── omission
│ ├── app.py
│ ├── common
│ │ ├── classproperty.py
│ │ ├── constants.py
│ │ ├── game_enums.py
│ │ └── __init__.py
│ ├── game
│ │ ├── content_loader.py
│ │ ├── game_item.py
│ │ ├── game_round.py
│ │ ├── __init__.py
│ │ └── timer.py
│ ├── __init__.py
│ ├── __main__.py
│ ├── resources
│ └── tests
│ ├── __init__.py
│ ├── test_game_item.py
│ ├── test_game_round_settings.py
│ ├── test_scoreboard.py
│ ├── test_settings.py
│ ├── test_test.py
│ └── test_timer.py
├── pylintrc
├── README.md
└── .gitignore
目錄結構來自[ 2 ]。
您可以嘗試設置:
(Windows) Ctrl + Shift + P →首選項:打開設置 (JSON) 。
將此行添加到您的用戶設置:
"python.terminal.executeInFileDir": true
其他系統的更全面的答案也在這個問題中。
方法有很多,如上所列,但我發現我只想導入一個文件的內容,不想寫一行行又非要導入其他模塊。 因此,我想出了一種獲取文件內容的方法,即使使用點語法( file.property
),而不是將導入的文件與您的文件合並。
首先,這是我要導入的文件data.py
testString= "A string literal to import and test with"
注意:您可以改用.txt
擴展名。
在mainfile.py
中,首先打開並獲取內容。
#!usr/bin/env python3
Data=open('data.txt','r+').read()
現在您將內容作為字符串,但嘗試訪問data.testString
會導致錯誤,因為data
是str
類的實例,即使它確實具有屬性testString
它也不會達到您的預期。
接下來,創建一個類。 例如(雙關語), ImportedFile
class ImportedFile:
並將其放入其中(帶有適當的縮進):
exec(data)
最后,像這樣重新分配data
:
data=ImportedFile()
就是這樣! 就像訪問任何其他模塊一樣,鍵入print(data.testString)
將打印到控制台A string literal to import and test with
。
但是,如果您想要from mod import *
的等價物,只需刪除類、實例分配並刪除exec
即可。
希望這可以幫助:)
-本吉
from y import *
然后轉到您的 x 文件並放置上述命令。 要測試這一點,只需在您的 y 文件中放置一個打印功能,當您的導入成功時,它應該在 x 文件中打印它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.