Làm cách nào để tìm thư mục chính của người dùng thực bằng python?


81

Tôi thấy rằng nếu chúng tôi thay đổi biến môi trường HOME (linux) hoặc USERPROFILE (windows) và chạy tập lệnh python, nó sẽ trả về giá trị mới là nhà người dùng khi tôi thử, os.environ ['HOME'] os.exp

Có cách nào để tìm thư mục chính của người dùng thực mà không cần dựa vào biến môi trường không?

chỉnh sửa:
Đây là một cách để tìm userhome trong windows bằng cách đọc trong sổ đăng ký,
http://mail.python.org/pipermail/python-win32/2008-January/006677.html

chỉnh sửa:
Một cách để tìm cửa sổ trang chủ bằng pywin32,

from win32com.shell import shell,shellcon
home = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, None, 0)

Bạn có thể muốn kiểm tra lệnh unix (phím tắt): ~userNó đưa bạn đến thư mục chính của người dùng hiện tại. Trên cửa sổ không có ý tưởng.
mAm

Điều này sẽ được đánh dấu là một bản sao của Cách lấy thư mục chính trong Python? vì câu trả lời được chấp nhận của câu hỏi đó hoạt động trên Python 3 còn câu hỏi này thì không.
Dour High Arch

Câu trả lời:


96

Tôi nghĩ os.path.expanduser(path)có thể hữu ích.

Trên Unix và Windows, trả về đối số bằng thành phần ban đầu ~ hoặc được ~userthay thế bằng thư mục chính của người dùng đó.

Trên Unix, một biến ban đầu ~được thay thế bằng biến môi trường HOME nếu nó được đặt; nếu không thì thư mục chính của người dùng hiện tại được tra cứu trong thư mục mật khẩu thông qua mô-đun tích hợp sẵn pwd. Tên viết tắt ~userđược tra cứu trực tiếp trong thư mục mật khẩu .

Trên Windows, HOME và USERPROFILE sẽ được sử dụng nếu được đặt, nếu không sẽ sử dụng kết hợp HOMEPATH và HOMEDRIVE . Ban đầu ~userđược xử lý bằng cách loại bỏ thành phần thư mục cuối cùng khỏi đường dẫn người dùng đã tạo dẫn xuất ở trên .

Nếu mở rộng không thành công hoặc nếu đường dẫn không bắt đầu bằng dấu ngã, đường dẫn được trả về không thay đổi.

Vì vậy, bạn chỉ có thể làm:

os.path.expanduser('~user')

3
Đúng, nhưng việc thay đổi biến môi trường như trong câu hỏi cũng sẽ "đánh lừa" phương pháp này. Bây giờ, tại sao một người muốn làm điều đó, tôi không thể nói. :)
Jakob Borg

1
@calmh: Vâng, tôi đã thay đổi nó để sử dụng '~user'sẽ hoạt động trên Linux và Windows (ở đây tôi không chắc chắn 100% vì tôi không có Windows để kiểm tra nó;)).
Felix Kling

1
Tính năng này hoạt động trong Linux, nhưng không hoạt động trong windows. Trong windows, nó chỉ tham gia "C: \ Documents and settings" với tên người dùng được chuyển.
asdfg

Điều này không giải quyết được vấn đề biến "HOME" bị sai. Ví dụ: xem cadence.com/Community/forums/t/17969.aspx
endolith

1
@asdfg: Đối với tôi, có vẻ như nó hoạt động chính xác. Nhưng tôi cũng nghĩ rằng nó đã thất bại trong lần đầu tiên tôi thử, bởi vì lúc đầu tôi đã chuyển chuỗi chữ '~ user' (thực sự cần phải là một cái gì đó theo nghĩa đen như '~ Bob') thay vì chỉ '~' (nối tiếp người dùng hiện tại).
Jon Coombs

17

Tôi nghĩ đây os.path.expanduser(path)là câu trả lời tốt nhất cho câu hỏi của bạn, nhưng có một giải pháp thay thế có thể đáng được nhắc đến trong thế giới Unix: pwdgói. ví dụ

import os, pwd

pwd.getpwuid(os.getuid()).pw_dir

1
Điều này rất hữu ích khi bạn muốn thư mục chính của người dùng, nhưng biến môi trường HOME được đặt không chính xác. Như tác giả đã lưu ý, nó không độc lập với nền tảng mà là dành cho UNIX, không phải Windows.
dùng1071847

1
Điều này tốt hơn là dựa vào biến HOME env có thể được giữ nguyên hoặc có thể không được duy trì trên các lệnh gọi sudo. Ví dụ HOME env. biến được thiết lập để người dùng mục tiêu trong Debian 8 ( 'sudo' đóng vai trò như 'sudo -H') nhưng được bảo quản trong Ubuntu 16 ( 'sudo' đóng vai trò như 'sudo -E')
Andrei Korostelev

16
from pathlib import *

str(Path.home())

hoạt động bằng Python 3.5 trở lên. Path.home()trả về một Pathđối tượng cung cấp một API mà tôi thấy rất hữu ích.


1
Về mặt nội bộ, pathlibvẫn dựa vào các biến môi trường, vì vậy điều này không trả lời câu hỏi cụ thể của bạn. Vì các câu hỏi chung chung hơn đều được đánh dấu là trùng lặp và tham khảo ở đây, đây có thể là nơi tốt nhất cho câu trả lời này.
Julius Kunze

pathlib là thư viện của tôi để xử lý đường dẫn ngay bây giờ! Không biết về .home (). Tôi sẽ phải xem lại các tài liệu một lần nữa để xem xét tất cả các tốt. Chúc mừng!
PlacidLush

5

home_folder = os.getenv('HOME')

Điều này cũng sẽ hoạt động trên Windows và Mac OS, hoạt động tốt trên Linux.


1
ít nhất điều này không hoạt động trên biến thể win10 coz có tên
HOMEPATH

@Reishin điều đó không hoàn toàn đúng, tôi vừa thử nghiệm nó và nó hoạt động trên Windows 10 Pro. Tôi thực sự không nghĩ rằng họ có thể đủ khả năng để thay đổi tên của một biến môi trường theo ý thích, với số lượng phần mềm mong đợi tìm thấy nó theo tên đó.
sm

@sm vui lòng thử tìm biến technet.microsoft.com/en-us/library/cc749104(v=ws.10).aspx "HOME" tại đây . Nếu bạn có biến tùy chỉnh, điều đó không có nghĩa là tất cả các ppl đều có nó. Trong hầu hết các trường hợp phổ biến, chẳng hạn như mingw, cygwin, git shell, v.v ... thiết lập nó cho bạn. Nhưng nếu bạn chạy cmd.exe, bạn sẽ ngạc nhiên
Reishin

4

Cho cửa sổ;

import os
homepath = os.path.expanduser(os.getenv('USERPROFILE'))

sẽ cung cấp cho bạn xử lý thư mục chính của người dùng hiện tại và

filepath = os.path.expanduser(os.getenv('USERPROFILE'))+'\\Documents\\myfile.txt'

sẽ cung cấp cho bạn một xử lý đối với tệp bên dưới;

C:\Users\urUserName\Documents\myfile.txt

3

Thực sự, một sự thay đổi trong biến môi trường chỉ ra rằng ngôi nhà phải được thay đổi. Vì vậy, mọi chương trình / kịch bản nên có ngôi nhà mới trong ngữ cảnh; còn hậu quả là tùy thuộc vào người đã thay đổi nó. Tôi vẫn sẽ gắn bó với home = os.getenv('USERPROFILE') or os.getenv('HOME')

chính xác những gì được yêu cầu?


5
Ngoại trừ Cygwin, trong trường hợp này, cả hai thường được xác định, và nhiều lần khác nhau.
amphetamachine

3

Tôi nhận ra rằng đây là một câu hỏi cũ đã được trả lời nhưng tôi nghĩ rằng tôi sẽ thêm hai xu của mình. Câu trả lời được chấp nhận không phù hợp với tôi. Tôi cần tìm thư mục người dùng và tôi muốn nó hoạt động có và không có sudo. Trong Linux, thư mục người dùng của tôi là "/ home / someuser" nhưng thư mục gốc của tôi là "/ root /". Tuy nhiên, trên máy Mac của tôi, thư mục người dùng là "/ Users / someuser". Đây là những gì tôi đã kết thúc:

_USERNAME = os.getenv("SUDO_USER") or os.getenv("USER") 
_HOME = os.path.expanduser('~'+_USERNAME)

Điều này hoạt động cả khi có và không có sudotrên Mac và Linux.


Tôi biết bạn nói Mac và Linux, nhưng trên Windows _USERNAMEthì có None. Dành cho độc giả trong tương lai.
Thomas Fauskanger

từ pathlib import Path; Path.home (). As_posix () # cũng hoạt động trong Windows. Cũng giống như phương pháp của Spronck, nó có thể tự nhiên hơn.
mikey

Nó sẽ là một cải tiến để làm cho nó hoạt động với các cửa sổ được thêm vào or ""?
PascalVKooten

0

Trên Linux và các UNIXoid khác, bạn luôn có thể xem qua /etc/passwd. Thư mục chính là trường thứ sáu được phân tách bằng dấu hai chấm trong đó. Tuy nhiên, không có ý tưởng về cách làm tốt hơn biến môi trường trên Windows. Sẽ có một lệnh gọi hệ thống cho nó, nhưng nếu nó có sẵn từ Python, ...


1
Nhưng đó sẽ chỉ là Unix (Linux) phải không?
người đeo nhẫn,

1
@ring - vâng. Đã thêm văn bản vào hiệu ứng đó.
Jakob Borg

-1

lấy (đã dịch) tên thư mục người dùng trên Linux:

from gi.repository import GLib

docs = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)
desktop = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)
pics = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)
videos = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)
music = GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)
downloads = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
public = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE)
templates = GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES)

print(docs)
print(desktop)
print(pics)
print(videos)
print(music)
print(downloads)
print(public)
print(templates)

dịch như thế nào?
gerrit

Được dịch sang ngôn ngữ hệ điều hành.
Axel Schneider
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.