كيفية الحصول على/تعيين مسار الدليل المنطقي في بيثون
سؤال
في بايثون، هل من الممكن الحصول على دليل منطقي أو تعيينه (على عكس الدليل المطلق).
على سبيل المثال إذا كان لدي:
/real/path/to/dir
و انا املك
/linked/path/to/dir
مرتبطة بنفس الدليل.
باستخدام os.getcwd وos.chdir سوف يستخدم دائمًا المسار المطلق
>>> import os
>>> os.chdir('/linked/path/to/dir')
>>> print os.getcwd()
/real/path/to/dir
الطريقة الوحيدة التي وجدتها للتغلب على هذا الأمر على الإطلاق هي إطلاق "pwd" في عملية أخرى وقراءة الإخراج.ومع ذلك، يعمل هذا فقط حتى تقوم بالاتصال بـ os.chdir للمرة الأولى.
المحلول
يُبلغ نظام التشغيل / Shell الأساسي عن مسارات حقيقية لـ python.
لذلك، لا توجد طريقة للتغلب على ذلك، منذ ذلك الحين os.getcwd()
هي دعوة ملفوفة لمكتبة C getcwd()
وظيفة.
هناك بعض الحلول البديلة لتلك التي تعرفها بالفعل والتي سيتم إطلاقها pwd
.
واحد آخر سوف ينطوي على استخدام os.environ['PWD']
.إذا تم تعيين متغير البيئة هذا، فيمكنك إجراء بعض التغييرات getcwd
الوظيفة التي تحترمها.
الحل أدناه يجمع بين الاثنين:
import os
from subprocess import Popen, PIPE
class CwdKeeper(object):
def __init__(self):
self._cwd = os.environ.get("PWD")
if self._cwd is None: # no environment. fall back to calling pwd on shell
self._cwd = Popen('pwd', stdout=PIPE).communicate()[0].strip()
self._os_getcwd = os.getcwd
self._os_chdir = os.chdir
def chdir(self, path):
if not self._cwd:
return self._os_chdir(path)
p = os.path.normpath(os.path.join(self._cwd, path))
result = self._os_chdir(p)
self._cwd = p
os.environ["PWD"] = p
return result
def getcwd(self):
if not self._cwd:
return self._os_getcwd()
return self._cwd
cwd = CwdKeeper()
print cwd.getcwd()
# use only cwd.chdir and cwd.getcwd from now on.
# monkeypatch os if you want:
os.chdir = cwd.chdir
os.getcwd = cwd.getcwd
# now you can use os.chdir and os.getcwd as normal.
نصائح أخرى
وهذا أيضًا يخدعني:
import os
os.popen('pwd').read().strip('\n')
هنا عرض توضيحي في بيثون شل:
>>> import os
>>> os.popen('pwd').read()
'/home/projteam/staging/site/proj\n'
>>> os.popen('pwd').read().strip('\n')
'/home/projteam/staging/site/proj'
>>> # Also works if PWD env var is set
>>> os.getenv('PWD')
'/home/projteam/staging/site/proj'
>>> # This gets actual path, not symlinked path
>>> import subprocess
>>> p = subprocess.Popen('pwd', stdout=subprocess.PIPE)
>>> p.communicate()[0] # returns non-symlink path
'/home/projteam/staging/deploys/20150114-141114/site/proj\n'
الحصول على متغير البيئة PWD لم يكن يعمل دائمًا بالنسبة لي لذا أستخدم طريقة popen.هتافات!