Python 獲取當(dāng)前目錄的多種方法(各種方法詳解)
概述
在 Python 中,獲取當(dāng)前目錄通常指的是兩種不同的概念:當(dāng)前工作目錄(Current Working Directory)和當(dāng)前腳本文件所在目錄。下面詳細(xì)介紹各種方法。
1. 獲取當(dāng)前工作目錄(CWD)
當(dāng)前工作目錄是程序執(zhí)行時(shí)所在的目錄。
import os
# 1. 使用 os.getcwd() - 最常用方法
current_working_dir = os.getcwd()
print(f"當(dāng)前工作目錄 (os.getcwd()): {current_working_dir}")
# 2. 使用 os.path 的快捷方式
cwd = os.path.curdir # 返回 '.',表示當(dāng)前目錄
print(f"當(dāng)前目錄符號 (os.path.curdir): {cwd}")
print(f"轉(zhuǎn)換為絕對路徑: {os.path.abspath(cwd)}")
# 3. 使用 pathlib 模塊 (Python 3.4+)
from pathlib import Path
cwd_pathlib = Path.cwd()
print(f"當(dāng)前工作目錄 (Path.cwd()): {cwd_pathlib}")
print(f"轉(zhuǎn)換為字符串: {str(cwd_pathlib)}")
# 4. 使用 os.environ 獲取 PWD 環(huán)境變量(Linux/Mac)
if 'PWD' in os.environ:
print(f"環(huán)境變量 PWD: {os.environ['PWD']}")
# 5. 工作目錄操作示例
print("\n工作目錄相關(guān)操作:")
print(f"目錄是否存在: {os.path.exists(current_working_dir)}")
print(f"是否為目錄: {os.path.isdir(current_working_dir)}")
print(f"目錄下的文件列表: {os.listdir(current_working_dir)[:5]}") # 顯示前5個(gè)2. 獲取當(dāng)前腳本文件所在目錄
import os
import sys
# 1. 使用 __file__ 屬性
def get_script_directory():
"""獲取當(dāng)前腳本文件所在目錄"""
# 獲取當(dāng)前文件的絕對路徑
if '__file__' in globals():
script_path = os.path.abspath(__file__)
return os.path.dirname(script_path)
else:
# 如果在交互式環(huán)境或某些特殊情況下
return os.getcwd()
script_dir = get_script_directory()
print(f"腳本文件所在目錄: {script_dir}")
# 2. 使用 pathlib
from pathlib import Path
def get_script_dir_pathlib():
"""使用 pathlib 獲取腳本目錄"""
try:
# 獲取當(dāng)前文件的絕對路徑
script_path = Path(__file__).resolve()
return script_path.parent
except NameError:
# 如果沒有 __file__ 屬性
return Path.cwd()
script_dir_pathlib = get_script_dir_pathlib()
print(f"腳本目錄 (pathlib): {script_dir_pathlib}")
# 3. 在函數(shù)內(nèi)部獲取調(diào)用者腳本的目錄
def get_caller_directory():
"""獲取調(diào)用者腳本的目錄"""
import inspect
# 獲取調(diào)用棧信息
frame = inspect.currentframe()
try:
# 向上回溯一幀,獲取調(diào)用者的信息
caller_frame = frame.f_back
caller_file = caller_frame.f_globals.get('__file__', '')
if caller_file:
return os.path.dirname(os.path.abspath(caller_file))
else:
return os.getcwd()
finally:
del frame # 避免循環(huán)引用
print(f"調(diào)用者目錄: {get_caller_directory()}")3. 兩種目錄的區(qū)別
import os
def demonstrate_directory_differences():
"""演示工作目錄和腳本目錄的區(qū)別"""
print("=== 目錄類型比較 ===")
# 獲取工作目錄
working_dir = os.getcwd()
print(f"當(dāng)前工作目錄: {working_dir}")
# 獲取腳本目錄
script_dir = os.path.dirname(os.path.abspath(__file__)) if '__file__' in globals() else working_dir
print(f"腳本文件目錄: {script_dir}")
# 比較兩者是否相同
if working_dir == script_dir:
print("? 工作目錄和腳本目錄相同")
else:
print("? 工作目錄和腳本目錄不同")
print(f" 差異: {os.path.relpath(script_dir, working_dir)}")
# 查看父目錄
working_parent = os.path.dirname(working_dir)
script_parent = os.path.dirname(script_dir)
print(f"\n工作目錄的父目錄: {working_parent}")
print(f"腳本目錄的父目錄: {script_parent}")
# 顯示目錄結(jié)構(gòu)
print("\n工作目錄內(nèi)容:")
for item in sorted(os.listdir(working_dir))[:5]: # 只顯示前5個(gè)
item_path = os.path.join(working_dir, item)
item_type = "目錄" if os.path.isdir(item_path) else "文件"
print(f" {item_type}: {item}")
demonstrate_directory_differences()4. 實(shí)用工具函數(shù)
import os
import sys
from pathlib import Path
class DirectoryUtils:
"""目錄工具類"""
@staticmethod
def get_working_dir():
"""獲取當(dāng)前工作目錄"""
return os.getcwd()
@staticmethod
def get_script_dir():
"""獲取腳本文件所在目錄"""
if getattr(sys, 'frozen', False):
# 如果是打包后的可執(zhí)行文件
return os.path.dirname(sys.executable)
elif '__file__' in globals():
# 正常Python腳本
return os.path.dirname(os.path.abspath(__file__))
else:
# 交互式環(huán)境
return os.getcwd()
@staticmethod
def get_home_dir():
"""獲取用戶主目錄"""
return os.path.expanduser('~')
@staticmethod
def get_temp_dir():
"""獲取臨時(shí)目錄"""
return os.path.join(os.path.expanduser('~'), 'tmp')
@staticmethod
def list_subdirectories(path=None):
"""列出指定目錄下的所有子目錄"""
if path is None:
path = os.getcwd()
dirs = []
for item in os.listdir(path):
item_path = os.path.join(path, item)
if os.path.isdir(item_path):
dirs.append(item)
return sorted(dirs)
@staticmethod
def list_files(path=None, extensions=None):
"""列出指定目錄下的文件"""
if path is None:
path = os.getcwd()
files = []
for item in os.listdir(path):
item_path = os.path.join(path, item)
if os.path.isfile(item_path):
if extensions is None:
files.append(item)
else:
ext = os.path.splitext(item)[1].lower()
if ext in extensions:
files.append(item)
return sorted(files)
@staticmethod
def create_directory(path):
"""創(chuàng)建目錄(如果不存在)"""
if not os.path.exists(path):
os.makedirs(path)
return True
return False
# 使用工具類
print("目錄工具類演示:")
utils = DirectoryUtils()
print(f"工作目錄: {utils.get_working_dir()}")
print(f"腳本目錄: {utils.get_script_dir()}")
print(f"用戶主目錄: {utils.get_home_dir()}")
print(f"臨時(shí)目錄: {utils.get_temp_dir()}")
# 列出當(dāng)前目錄的子目錄
print(f"\n當(dāng)前目錄下的子目錄: {utils.list_subdirectories()[:5]}...") # 顯示前5個(gè)
# 列出當(dāng)前目錄的Python文件
print(f"當(dāng)前目錄下的Python文件: {utils.list_files(extensions=['.py'])}")5. 動態(tài)改變當(dāng)前目錄
import os
def demonstrate_directory_changes():
"""演示如何改變當(dāng)前目錄"""
original_dir = os.getcwd()
print(f"原始工作目錄: {original_dir}")
# 1. 使用 os.chdir() 改變目錄
try:
# 嘗試切換到上級目錄
parent_dir = os.path.dirname(original_dir)
os.chdir(parent_dir)
print(f"切換到父目錄: {os.getcwd()}")
# 再切換回來
os.chdir(original_dir)
print(f"切換回原始目錄: {os.getcwd()}")
except Exception as e:
print(f"切換目錄出錯: {e}")
# 確保切換回原始目錄
os.chdir(original_dir)
# 2. 臨時(shí)切換目錄(使用上下文管理器)
class ChangeDirectory:
"""上下文管理器,用于臨時(shí)切換目錄"""
def __init__(self, new_path):
self.new_path = new_path
self.original_path = None
def __enter__(self):
self.original_path = os.getcwd()
os.chdir(self.new_path)
print(f"進(jìn)入目錄: {os.getcwd()}")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
os.chdir(self.original_path)
print(f"退出到目錄: {os.getcwd()}")
return False # 不抑制異常
# 使用上下文管理器
print("\n使用上下文管理器切換目錄:")
# 嘗試切換到臨時(shí)目錄
temp_dir = os.path.join(original_dir, "temp_test")
os.makedirs(temp_dir, exist_ok=True)
with ChangeDirectory(temp_dir):
print(f"在臨時(shí)目錄中,創(chuàng)建測試文件...")
test_file = os.path.join(temp_dir, "test.txt")
with open(test_file, "w") as f:
f.write("測試內(nèi)容")
print(f"已創(chuàng)建文件: {test_file}")
print(f"返回后的目錄: {os.getcwd()}")
# 清理測試目錄
os.remove(test_file)
os.rmdir(temp_dir)
demonstrate_directory_changes()6. 特殊場景處理
import os
import sys
def handle_special_cases():
"""處理獲取目錄的特殊場景"""
print("=== 特殊場景處理 ===")
# 1. 打包為可執(zhí)行文件的情況
if getattr(sys, 'frozen', False):
# 如果是 PyInstaller 或類似工具打包的
application_path = os.path.dirname(sys.executable)
print(f"打包應(yīng)用路徑: {application_path}")
else:
print("正常Python腳本環(huán)境")
# 2. 交互式環(huán)境(如 Jupyter, IPython)
try:
# 檢查是否在 Jupyter 環(huán)境中
from IPython import get_ipython
if get_ipython() is not None:
print("在 Jupyter/IPython 環(huán)境中")
print(f"啟動目錄: {os.getcwd()}")
except ImportError:
pass
# 3. 模塊導(dǎo)入的情況
def get_module_path(module_name):
"""獲取已安裝模塊的路徑"""
try:
import importlib
module = importlib.import_module(module_name)
if hasattr(module, '__file__'):
return os.path.dirname(os.path.abspath(module.__file__))
return None
except ImportError:
return None
# 獲取 os 模塊的路徑
os_module_path = get_module_path('os')
if os_module_path:
print(f"os 模塊路徑: {os_module_path}")
# 4. 處理符號鏈接
if '__file__' in globals():
real_path = os.path.realpath(__file__)
link_path = __file__
if real_path != os.path.abspath(link_path):
print(f"腳本是符號鏈接")
print(f" 鏈接位置: {link_path}")
print(f" 實(shí)際位置: {real_path}")
# 5. 處理相對路徑
relative_path = "./test_dir"
absolute_path = os.path.abspath(relative_path)
print(f"\n相對路徑轉(zhuǎn)換:")
print(f" 相對路徑: {relative_path}")
print(f" 絕對路徑: {absolute_path}")
# 標(biāo)準(zhǔn)化路徑
normalized = os.path.normpath(absolute_path)
print(f" 標(biāo)準(zhǔn)化路徑: {normalized}")
handle_special_cases()7. 實(shí)用示例:項(xiàng)目目錄管理
import os
from pathlib import Path
class ProjectDirectory:
"""項(xiàng)目目錄管理類"""
def __init__(self, project_root=None):
"""初始化項(xiàng)目目錄管理器"""
if project_root is None:
# 默認(rèn)使用當(dāng)前腳本的父目錄作為項(xiàng)目根目錄
self.project_root = self._find_project_root()
else:
self.project_root = Path(project_root).resolve()
# 創(chuàng)建標(biāo)準(zhǔn)目錄結(jié)構(gòu)
self.dirs = {
'data': self.project_root / 'data',
'logs': self.project_root / 'logs',
'src': self.project_root / 'src',
'tests': self.project_root / 'tests',
'docs': self.project_root / 'docs',
'config': self.project_root / 'config'
}
# 確保所有目錄都存在
self._ensure_directories()
def _find_project_root(self):
"""查找項(xiàng)目根目錄"""
# 從當(dāng)前腳本目錄開始,向上查找包含特定標(biāo)識的目錄
current = Path(__file__).resolve().parent if '__file__' in globals() else Path.cwd()
# 查找包含 .git 或 setup.py 等標(biāo)識的目錄
markers = ['.git', 'setup.py', 'pyproject.toml', 'requirements.txt']
for marker in markers:
for parent in [current] + list(current.parents):
if (parent / marker).exists():
return parent
# 如果沒有找到標(biāo)識,使用當(dāng)前目錄的父目錄
return current
def _ensure_directories(self):
"""確保所有必要的目錄都存在"""
for name, path in self.dirs.items():
path.mkdir(parents=True, exist_ok=True)
def get_path(self, name, *subpaths):
"""獲取目錄路徑"""
if name not in self.dirs:
raise ValueError(f"未知的目錄名: {name}")
return str(self.dirs[name].joinpath(*subpaths))
def list_files(self, directory, pattern="*"):
"""列出目錄中的文件"""
if directory not in self.dirs:
raise ValueError(f"未知的目錄名: {directory}")
return [str(f) for f in self.dirs[directory].glob(pattern)]
def report(self):
"""生成目錄結(jié)構(gòu)報(bào)告"""
print("=== 項(xiàng)目目錄結(jié)構(gòu) ===")
print(f"項(xiàng)目根目錄: {self.project_root}")
print("\n目錄列表:")
for name, path in sorted(self.dirs.items()):
files_count = len(list(path.glob("*")))
print(f" {name:10}: {path} ({files_count} 個(gè)項(xiàng)目)")
print(f"\n當(dāng)前工作目錄: {os.getcwd()}")
print(f"相對路徑: {os.path.relpath(os.getcwd(), self.project_root)}")
# 使用示例
if __name__ == "__main__":
print("項(xiàng)目目錄管理示例:")
# 創(chuàng)建項(xiàng)目目錄管理器
project = ProjectDirectory()
# 顯示目錄結(jié)構(gòu)
project.report()
# 獲取特定目錄的路徑
print(f"\n數(shù)據(jù)目錄: {project.get_path('data')}")
print(f"日志目錄: {project.get_path('logs')}")
# 創(chuàng)建文件示例
log_file = os.path.join(project.get_path('logs'), 'app.log')
with open(log_file, 'w') as f:
f.write("日志開始\n")
print(f"已創(chuàng)建日志文件: {log_file}")8. 性能比較
import os
import time
from pathlib import Path
def compare_performance():
"""比較不同獲取目錄方法的性能"""
test_count = 100000
print("性能比較(執(zhí)行100,000次):")
# 測試 os.getcwd()
start = time.time()
for _ in range(test_count):
_ = os.getcwd()
end = time.time()
print(f"os.getcwd(): {(end-start)*1000:.2f} ms")
# 測試 Path.cwd()
start = time.time()
for _ in range(test_count):
_ = Path.cwd()
end = time.time()
print(f"Path.cwd(): {(end-start)*1000:.2f} ms")
# 測試 os.path.abspath('.')
start = time.time()
for _ in range(test_count):
_ = os.path.abspath('.')
end = time.time()
print(f"os.path.abspath('.'): {(end-start)*1000:.2f} ms")
# 測試 os.path.dirname(os.path.abspath(__file__))
if '__file__' in globals():
start = time.time()
for _ in range(test_count):
_ = os.path.dirname(os.path.abspath(__file__))
end = time.time()
print(f"os.path.dirname(__file__): {(end-start)*1000:.2f} ms")
# 運(yùn)行性能測試
print("獲取目錄方法性能比較:")
compare_performance()這些方法涵蓋了 Python 中獲取當(dāng)前目錄的各種場景和需求。根據(jù)具體需求選擇合適的方法:
- 獲取工作目錄:使用
os.getcwd()或Path.cwd() - 獲取腳本目錄:使用
os.path.dirname(os.path.abspath(__file__))或Path(__file__).resolve().parent - 需要路徑操作:推薦使用
pathlib模塊 - 需要兼容舊版本:使用
os.path模塊
到此這篇關(guān)于Python 獲取當(dāng)前目錄的多種方法的文章就介紹到這了,更多相關(guān)python獲取當(dāng)前目錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python opencv實(shí)現(xiàn)任意角度的透視變換實(shí)例代碼
這篇文章主要介紹了python opencv實(shí)現(xiàn)任意角度的透視變換實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
學(xué)習(xí)Python selenium自動化網(wǎng)頁抓取器
本篇文章給大家介紹了Python selenium自動化網(wǎng)頁抓取器的實(shí)例應(yīng)用以及知識點(diǎn)分析,有需要的參考學(xué)習(xí)下。2018-01-01
Python數(shù)據(jù)可視化圖實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Python數(shù)據(jù)可視化圖實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
python fuzzywuzzy模塊模糊字符串匹配詳細(xì)用法
這篇文章主要介紹了使用Python完成公司名稱和地址的模糊匹配的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
利用LyScript實(shí)現(xiàn)應(yīng)用層鉤子掃描器
Capstone 是一個(gè)輕量級的多平臺、多架構(gòu)的反匯編框架。本篇文章將運(yùn)用LyScript插件結(jié)合Capstone反匯編引擎實(shí)現(xiàn)一個(gè)鉤子掃描器,感興趣的可以了解一下2022-08-08
解決Pyinstaller 打包exe文件 取消dos窗口(黑框框)的問題
今天小編就為大家分享一篇解決Pyinstaller 打包exe文件 取消dos窗口(黑框框)的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06
python創(chuàng)建虛擬環(huán)境的3種方式
在Python開發(fā)中,主要有三種創(chuàng)建虛擬環(huán)境的方式,包括conda、pyenv+pyenv-virtualenv和venv,它們各有特點(diǎn)和適用場景,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-02-02

