NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
В Mac OS вы можете использовать команду «open». Существует вызов Windows API, который делает что-то подобное, но я не помню его вслух.
Хорошо, команда «start» сделает это, так что это должно работать
Mac OS / X:
os.system("open "+filename)
Windows:
os.system("start "+filename)
Хорошо, ясно, что это глупое споры продолжаются, поэтому давайте просто посмотрим на это с помощью подпроцесса.
open
и start
являются средствами интерпретатора команд для Mac OS / X и Windows соответственно. Теперь предположим, что мы используем подпроцесс. Канонически вы бы использовали:
try:
retcode = subprocess.call("open " + filename, shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e
. Каковы преимущества этого? Теоретически это более безопасно - но на самом деле нам нужно выполнить командную строку так или иначе; в любой среде нам нужна среда и службы для интерпретации, получения путей и т. д. В любом случае мы не выполняем произвольный текст, поэтому он не имеет встроенного «но вы можете набрать 'filename ; rm -rf /'
», и если имя файла может быть повреждено, использование subprocess.call
не дает нам никакой защиты.
Это фактически не дает нам больше обнаружения ошибок, мы все еще в зависимости от retcode
в любом случае. Нам не нужно ждать дочернего процесса, так как мы имеем дело с выражением проблемы, начиная отдельный процесс.
«Но subprocess
является предпочтительным». Однако os.system()
не является устаревшим, и это самый простой инструмент для этой конкретной работы.
Заключение: использование os.system()
- это самый простой и простой способ сделать это, и, следовательно, правильный ответ.
Я предпочитаю:
os.startfile(path, 'open')
Обратите внимание, что этот модуль поддерживает имена файлов, которые имеют пробелы в своих папках и файлах, например.
A:\abc\folder with spaces\file with-spaces.txt
( python docs ) 'open' не нужно добавлять (это значение по умолчанию). В документах упоминается, что это похоже на двойной щелчок на значке файла в Проводнике Windows.
Это решение - только окна.
Если вам нужно использовать эвристический метод, вы можете рассмотреть webbrowser
. Это стандартная библиотека и, несмотря на ее имя, она также попытается открыть файлы:
Обратите внимание, что на некоторых платформах, пытаясь открыть имя файла с помощью этой функции, может работать и запускать связанную с операционной системой программу , Однако это не поддерживается и не переносится. ( Ссылка )
Я пробовал этот код, и он отлично работал в Windows 7 и Ubuntu Natty:
import webbrowser webbrowser.open("path_to_file")
Этот код также работает отлично в Windows XP Professional, используя Internet Explorer 8.
open location
там, который должен работать, если вы укажете путь как действительный URL-адрес.
– jfs
7 August 2015 в 19:14
import webbrowser webbrowser.open("file:///Users/nameGoesHere/Desktop/folder/file.py")
– Dani Springer
17 December 2017 в 23:53
os.startfile (путь, 'open') под окнами хорош, потому что, когда в каталоге существуют пробелы, os.system ('start', path_name) не может правильно открыть приложение и когда i18n существует в каталоге , os.system необходимо изменить юникод на кодек консоли в Windows.
Start не поддерживает длинные имена путей и пробелы. Вы должны преобразовать его в 8.3 совместимые пути.
import subprocess
import win32api
filename = "C:\\Documents and Settings\\user\\Desktop\file.avi"
filename_short = win32api.GetShortPathName(filename)
subprocess.Popen('start ' + filename_short, shell=True )
Файл должен существовать, чтобы работать с вызовом API.
start "Title" "C:\long path to\file.avi"
– user3364825
21 May 2014 в 14:45
В Windows 8.1 ниже работали, в то время как другие заданные способы с subprocess.call
терпят неудачу с путём, в нем есть пробелы.
subprocess.call('cmd /c start "" "any file path with spaces"')
Используя этот и другие ответы раньше, вот встроенный код, который работает на нескольких платформах.
import sys, os, subprocess
subprocess.call(('cmd /c start "" "'+ filepath +'"') if os.name is 'nt' else ('open' if sys.platform.startswith('darwin') else 'xdg-open', filepath))
Просто для полноты (это не было в вопросе), xdg-open будет делать то же самое в Linux.
Если вы хотите пойти по пути subprocess.call()
, это должно выглядеть так, как в Windows:
import subprocess
subprocess.call(('cmd', '/C', 'start', '', FILE_NAME))
Вы не можете просто использовать:
subprocess.call(('start', FILE_NAME))
, потому что start
не является исполняемым файлом , а является командой программы cmd.exe
. Это работает:
subprocess.call(('cmd', '/C', 'start', FILE_NAME))
, но только в том случае, если в FILE_NAME нет пробелов.
Хотя метод subprocess.call
правильно задает параметры, команда start
имеет довольно странную синтаксис, где:
start notes.txt
делает что-то еще:
start "notes.txt"
В первой цитируемой строке следует указать заголовок окна. Чтобы заставить его работать с пробелами, мы должны сделать:
start "" "my notes.txt"
, что и делает код сверху.
Я довольно поздно для партии, но вот решение, использующее windows api. Это всегда открывает связанное приложение.
import ctypes
shell32 = ctypes.windll.shell32
file = 'somedocument.doc'
shell32.ShellExecuteA(0,"open",file,0,0,5)
Множество магических констант. Первый нуль - это hwnd текущей программы. Может быть нулевым. Остальные два нули - это необязательные параметры (параметры и каталог). 5 == SW_SHOW, он указывает, как выполнить приложение. Подробнее читайте в документах ShellExecute API .
на mac os вы можете вызвать 'open'
import os
os.popen("open myfile.txt")
, это откроет файл с помощью TextEdit или любое другое приложение будет установлено по умолчанию для этого типа файла
import os
import subprocess
def click_on_file(filename):
'''Open document with default application in Python.'''
try:
os.startfile(filename)
except AttributeError:
subprocess.call(['open', filename])
Используйте модуль subprocess
, доступный на Python 2.4+, а не os.system()
, поэтому вам не нужно иметь дело с экранированием оболочки.
import subprocess, os
if sys.platform.startswith('darwin'):
subprocess.call(('open', filepath))
elif os.name == 'nt':
os.startfile(filepath)
elif os.name == 'posix':
subprocess.call(('xdg-open', filepath))
Двойные круглые скобки связаны с тем, что subprocess.call()
хочет, чтобы в качестве первого аргумента была последовательность, поэтому мы используем кортеж здесь. В Linux-системах с Gnome есть также команда gnome-open
, которая делает то же самое, но xdg-open
является стандартом Free Desktop Foundation и работает в среде рабочего стола Linux.
xdg-open
- linux.die.net/man/1/xdg-open
– gnud
18 October 2009 в 20:57
Если вы хотите указать приложение для открытия файла с помощью Mac OS X, используйте это: os.system("open -a [app name] [file name]")
filename
, это прекрасный пример того, почему os.system () небезопасна и плоха. подпроцесс лучше. – Devin Jeanpierre 28 March 2009 в 17:36os.system()
заключается в том, что она использует оболочку (и вы не выполняете никаких экранов здесь, так что Bad Things будет происходить для вполне допустимых имен файлов, которые содержат метасимволы оболочки). Причина, по которойsubprocess.call()
является предпочтительной, заключается в том, что вы можете обойти оболочку с помощьюsubprocess.call(["open", filename])
. Это работает для всех допустимых имен файлов и не вызывает уязвимости оболочки, даже для ненадежных имен файлов. – Sven Marnach 23 April 2012 в 15:55