Почему я вынужден использовать os.path.expanduser в python?
Я уверен, что это намеренно, так может кто-то объяснить обоснование такого поведения:
Python 2.7.2 (default, Oct 13 2011, 15:27:47)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from os.path import isdir,expanduser
>>> isdir("~amosa/pdb")
False
>>> isdir(expanduser("~amosa/pdb"))
True
>>>
>>> from os import chdir
>>> chdir("~amosa/pdb")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '~amosa/pdb'
>>> chdir(expanduser("~amosa/pdb"))
>>>
Это действительно раздражает, поскольку в конце концов путь с именем пользователя в нем может быть однозначно разрешен... Я хочу написать код, который может обрабатывать любые входные данные, которые пользователь может мне дать, но это поведение требует от меня вызовите expanduser по каждому пути, с которым должен работать мой код. Это также означает, что где-либо я печатаю этот путь для просмотра пользователем, он будет немного менее разборчивым, чем то, что они мне дали.
Это кажется несовместимым с понятием "утиная типизация", в котором я обобщаю, что я ожидаю, что питон не будет скулить для меня, если на самом деле не проблема...
Ответы
Ответ 1
Поскольку базовые системные вызовы не распознают пути пользователя, а API доступа к файлам - довольно тонкая оболочка над ними.
Кроме того, это было бы довольно неожиданно для не-Unix-пользователей,
if (например) fopen("~foo")
возвращает ошибку "foo: no such user" (поскольку "~foo"
является допустимым именем файла, например, Windows)...
Или, аналогично, если fopen("~administrator")
возвращает ошибку, например "Является ли каталог: C:\Documents and Settings\Administrator \".
Наконец, как отмечают комментаторы: вы вводите в заблуждение "утиную печать" с "полезными ярлыками", которые являются двумя совершенно разными вещами:
- Утиная набивка позволяет мне заменить утку чем-нибудь, что может трясти как утка.
- Полезные ярлыки позволяют мне заменить утку чем-нибудь, что можно было бы сделать в шарлатанье, как утка. (Python не "пытается сделать это quack", как это делают некоторые другие языки).
Ответ 2
В обычных утилитах Unix синтаксис ~amosa
обрабатывается оболочкой, которая является программой, которая вызывает утилиты. Сами утилиты не знают о специальном синтаксисе ~
(обычно).
Итак, если ваша программа python вызывается оболочкой в Unix, она просто работает:
$ python -c 'import sys; print sys.argv[1]' ~drj
/home/drj
Обратите внимание, что программа python выше печатает расширенный путь, хотя у него явно нет кода для самого расширения. Оболочка расширила его.