cd
là lệnh shell để thay đổi thư mục làm việc.
Làm cách nào để thay đổi thư mục làm việc hiện tại trong Python?
os.getcwd()
cd
là lệnh shell để thay đổi thư mục làm việc.
Làm cách nào để thay đổi thư mục làm việc hiện tại trong Python?
os.getcwd()
Câu trả lời:
Bạn có thể thay đổi thư mục làm việc với:
import os
os.chdir(path)
Có hai cách tốt nhất để làm theo khi sử dụng phương pháp này:
Thay đổi thư mục làm việc hiện tại trong một quy trình con không thay đổi thư mục làm việc hiện tại trong quy trình cha. Điều này cũng đúng với trình thông dịch Python. Bạn không thể sử dụng os.chdir()
để thay đổi CWD của quá trình gọi.
os.chdir()
bên ngoài một người quản lý bối cảnh, trừ khi bạn nghĩ rằng bạn biết những gì bạn đang làm. ( Bạn có thể không. )
os.chdir("C:/path/to/location")
Đây là một ví dụ về trình quản lý bối cảnh để thay đổi thư mục làm việc. Nó đơn giản hơn phiên bản ActiveState được đề cập ở nơi khác, nhưng điều này hoàn thành công việc.
cd
import os
class cd:
"""Context manager for changing the current working directory"""
def __init__(self, newPath):
self.newPath = os.path.expanduser(newPath)
def __enter__(self):
self.savedPath = os.getcwd()
os.chdir(self.newPath)
def __exit__(self, etype, value, traceback):
os.chdir(self.savedPath)
Hoặc thử tương đương ngắn gọn hơn (bên dưới) , sử dụng ContextManager .
import subprocess # just to call an arbitrary command e.g. 'ls'
# enter the directory like this:
with cd("~/Library"):
# we are in ~/Library
subprocess.call("ls")
# outside the context manager we are back wherever we started.
return self
vào cuối __enter__
. Bằng cách đó bạn có thể làm with cd('foo') as cm:
và truy cập thư mục trước nhưcm.savedPath
Tôi sẽ sử dụng os.chdir
như thế này:
os.chdir("/path/to/change/to")
Nhân tiện, nếu bạn cần tìm ra con đường hiện tại của mình, hãy sử dụng os.getcwd()
.
Thêm ở đây
cd()
là dễ dàng để viết bằng cách sử dụng một máy phát điện và trang trí.
from contextlib import contextmanager
import os
@contextmanager
def cd(newdir):
prevdir = os.getcwd()
os.chdir(os.path.expanduser(newdir))
try:
yield
finally:
os.chdir(prevdir)
Sau đó, thư mục được hoàn nguyên ngay cả sau khi ném ngoại lệ:
os.chdir('/home')
with cd('/tmp'):
# ...
raise Exception("There's no place like home.")
# Directory is now back to '/home'.
try/finally
).
yield
và không return
? Đây có phải là một máy phát điện?
Nếu bạn đang sử dụng phiên bản Python tương đối mới, bạn cũng có thể sử dụng trình quản lý bối cảnh, chẳng hạn như phiên bản này :
from __future__ import with_statement
from grizzled.os import working_directory
with working_directory(path_to_directory):
# code in here occurs within the directory
# code here is in the original directory
CẬP NHẬT
Nếu bạn thích tự cuộn:
import os
from contextlib import contextmanager
@contextmanager
def working_directory(directory):
owd = os.getcwd()
try:
os.chdir(directory)
yield directory
finally:
os.chdir(owd)
contextlib.contextmanager
là tốt. Xem câu trả lời dựa trên trang trí của cdunn2001 , lý tưởng nhất sẽ là câu trả lời được chấp nhận ngay bây giờ.
Như đã được chỉ ra bởi những người khác, tất cả các giải pháp ở trên chỉ thay đổi thư mục làm việc của quy trình hiện tại. Điều này bị mất khi bạn thoát trở lại shell Unix. Nếu tuyệt vọng, bạn có thể thay đổi thư mục shell cha trên Unix với bản hack khủng khiếp này:
def quote_against_shell_expansion(s):
import pipes
return pipes.quote(s)
def put_text_back_into_terminal_input_buffer(text):
# use of this means that it only works in an interactive session
# (and if the user types while it runs they could insert characters between the characters in 'text'!)
import fcntl, termios
for c in text:
fcntl.ioctl(1, termios.TIOCSTI, c)
def change_parent_process_directory(dest):
# the horror
put_text_back_into_terminal_input_buffer("cd "+quote_against_shell_expansion(dest)+"\n")
os.chdir()
là cách đúng đắn
import os
abs_path = 'C://a/b/c'
rel_path = './folder'
os.chdir(abs_path)
os.chdir(rel_path)
Bạn có thể sử dụng cả hai với os.chdir (abs_path) hoặc os.chdir (rel_path), không cần phải gọi os.getcwd () để sử dụng đường dẫn tương đối.
Tiếp tục đi vào hướng được chỉ ra bởi Brian và dựa trên sh (1.0.8+)
from sh import cd, ls
cd('/tmp')
print ls()
Nếu bạn sử dụng spyder và yêu GUI, bạn chỉ cần nhấp vào nút thư mục ở góc trên bên phải màn hình của bạn và điều hướng qua các thư mục / thư mục bạn muốn làm thư mục hiện tại. Sau khi làm như vậy, bạn có thể chuyển đến tab trình duyệt tệp của cửa sổ trong IDE gián điệp và bạn có thể thấy tất cả các tệp / thư mục có trong đó. để kiểm tra thư mục làm việc hiện tại của bạn, hãy vào bảng điều khiển của IDE gián điệp và chỉ cần gõ
pwd
nó sẽ in cùng một đường dẫn như bạn đã chọn trước đó.
Thay đổi thư mục hiện tại của quá trình tập lệnh là chuyện nhỏ. Tôi nghĩ rằng câu hỏi thực sự là làm thế nào để thay đổi thư mục hiện tại của cửa sổ lệnh mà từ đó một kịch bản python được gọi, điều này rất khó. Tập lệnh Bat trong Windows hoặc tập lệnh Bash trong trình bao Bash có thể thực hiện việc này bằng lệnh cd thông thường vì chính trình bao là trình thông dịch. Trong cả Windows và Linux Python là một chương trình và không có chương trình nào có thể thay đổi trực tiếp môi trường của cha mẹ nó. Tuy nhiên, sự kết hợp của tập lệnh shell đơn giản với tập lệnh Python thực hiện hầu hết các nội dung cứng có thể đạt được kết quả mong muốn. Ví dụ, để tạo một lệnh cd mở rộng với lịch sử truyền tải cho truy cập ngược / tiến / chọn, tôi đã viết một tập lệnh Python tương đối phức tạp được gọi bởi một tập lệnh bat đơn giản. Danh sách truyền tải được lưu trữ trong một tệp, với thư mục đích trên dòng đầu tiên. Khi tập lệnh python trả về, tập lệnh bat đọc dòng đầu tiên của tập tin và biến nó thành đối số thành cd. Kịch bản dơi hoàn chỉnh (trừ bình luận cho ngắn gọn) là:
if _%1 == _. goto cdDone
if _%1 == _? goto help
if /i _%1 NEQ _-H goto doCd
:help
echo d.bat and dSup.py 2016.03.05. Extended chdir.
echo -C = clear traversal list.
echo -B or nothing = backward (to previous dir).
echo -F or - = forward (to next dir).
echo -R = remove current from list and return to previous.
echo -S = select from list.
echo -H, -h, ? = help.
echo . = make window title current directory.
echo Anything else = target directory.
goto done
:doCd
%~dp0dSup.py %1
for /F %%d in ( %~dp0dSupList ) do (
cd %%d
if errorlevel 1 ( %~dp0dSup.py -R )
goto cdDone
)
:cdDone
title %CD%
:done
Kịch bản python, dSup.py là:
import sys, os, msvcrt
def indexNoCase ( slist, s ) :
for idx in range( len( slist )) :
if slist[idx].upper() == s.upper() :
return idx
raise ValueError
# .........main process ...................
if len( sys.argv ) < 2 :
cmd = 1 # No argument defaults to -B, the most common operation
elif sys.argv[1][0] == '-':
if len(sys.argv[1]) == 1 :
cmd = 2 # '-' alone defaults to -F, second most common operation.
else :
cmd = 'CBFRS'.find( sys.argv[1][1:2].upper())
else :
cmd = -1
dir = os.path.abspath( sys.argv[1] ) + '\n'
# cmd is -1 = path, 0 = C, 1 = B, 2 = F, 3 = R, 4 = S
fo = open( os.path.dirname( sys.argv[0] ) + '\\dSupList', mode = 'a+t' )
fo.seek( 0 )
dlist = fo.readlines( -1 )
if len( dlist ) == 0 :
dlist.append( os.getcwd() + '\n' ) # Prime new directory list with current.
if cmd == 1 : # B: move backward, i.e. to previous
target = dlist.pop(0)
dlist.append( target )
elif cmd == 2 : # F: move forward, i.e. to next
target = dlist.pop( len( dlist ) - 1 )
dlist.insert( 0, target )
elif cmd == 3 : # R: remove current from list. This forces cd to previous, a
# desireable side-effect
dlist.pop( 0 )
elif cmd == 4 : # S: select from list
# The current directory (dlist[0]) is included essentially as ESC.
for idx in range( len( dlist )) :
print( '(' + str( idx ) + ')', dlist[ idx ][:-1])
while True :
inp = msvcrt.getche()
if inp.isdigit() :
inp = int( inp )
if inp < len( dlist ) :
print( '' ) # Print the newline we didn't get from getche.
break
print( ' is out of range' )
# Select 0 means the current directory and the list is not changed. Otherwise
# the selected directory is moved to the top of the list. This can be done by
# either rotating the whole list until the selection is at the head or pop it
# and insert it to 0. It isn't obvious which would be better for the user but
# since pop-insert is simpler, it is used.
if inp > 0 :
dlist.insert( 0, dlist.pop( inp ))
elif cmd == -1 : # -1: dir is the requested new directory.
# If it is already in the list then remove it before inserting it at the head.
# This takes care of both the common case of it having been recently visited
# and the less common case of user mistakenly requesting current, in which
# case it is already at the head. Deleting and putting it back is a trivial
# inefficiency.
try:
dlist.pop( indexNoCase( dlist, dir ))
except ValueError :
pass
dlist = dlist[:9] # Control list length by removing older dirs (should be
# no more than one).
dlist.insert( 0, dir )
fo.truncate( 0 )
if cmd != 0 : # C: clear the list
fo.writelines( dlist )
fo.close()
exit(0)
os.chdir(os.path.join(os.path.abspath(os.path.curdir),u'subfolder'))
- hay?