Pytanie numer 10501247 w stackoverflow daje odpowiedź, jak utworzyć plik tymczasowy w Pythonie.
W moim przypadku potrzebuję tylko tymczasowej nazwy pliku.
Wywołanie tempfile.NamedTemporaryFile () zwraca uchwyt pliku po jego utworzeniu.
Czy jest sposób, aby uzyskać tylko nazwę pliku?
# Trying to get temp file path
tf = tempfile.NamedTemporaryFile()
temp_file_name = tf.name
tf.close()
# Here is my real purpose to get the temp_file_name
f = gzip.open(temp_file_name ,'wb')
...
python
temporary-files
Wzgórze
źródło
źródło
NamedTemporaryFile
gwarantuje unikalną nazwę (prawdopodobnie), wypróbowując ją i ponawiając próbę, jeśli istnieje. Uzyskanie samej nazwy nie gwarantuje, że będziesz mógł faktycznie utworzyć plik później, otwierasz się na warunki rasy kogoś innego, kto używa tej samej nazwy przed tobą.Odpowiedzi:
Jeśli chcesz mieć tylko nazwę pliku tymczasowego, możesz wywołać funkcję wewnętrznego pliku tymczasowego
_get_candidate_names()
:import tempfile temp_name = next(tempfile._get_candidate_names()) % e.g. px9cp65s
next
Ponowne wywołanie zwróci inną nazwę itp. Nie daje to ścieżki do folderu tymczasowego. Aby uzyskać domyślny katalog „tmp”, użyj:defult_tmp_dir = tempfile._get_default_tempdir() % results in: /tmp
źródło
temp_dir = tempfile.mkdtemp(prefix='some-prefix_')
bezpieczne utworzenie katalogu tymczasowego i zwrócenie ciągu znaków z bezwzględną ścieżką.next(tempfile._get_candidate_names())
niekoniecznie zwraca nieistniejącą ścieżkę, dlatego interfejsy plików tymczasowych na poziomie użytkownika mogą wypróbować kilka nazw, dopóki nie zostanie znaleziona nieużywana :tempfile.gettempdir()
zamiast prywatnegotempfile._get_default_tempdir()
.tempfile.mkdtemp
użytkownik jest odpowiedzialny za usunięcie katalogu tymczasowego i jego zawartości po zakończeniu korzystania z niego.Myślę, że najłatwiejszym i najbezpieczniejszym sposobem na zrobienie tego jest coś takiego:
path = os.path.join(tempfile.mkdtemp(), 'something')
Tworzony jest katalog tymczasowy, do którego tylko Ty masz dostęp, więc nie powinno być problemów z bezpieczeństwem, ale nie będą w nim tworzone żadne pliki, więc możesz po prostu wybrać dowolną nazwę pliku, którą chcesz utworzyć w tym katalogu.
edycja: w Pythonie 3 możesz teraz używać
tempfile.TemporaryDirectory()
jako menedżera kontekstu do obsługi usuwania:with tempfile.TemporaryDirectory() as tmp: path = os.path.join(tmp, 'something') # use path
źródło
tempfile.mkdtemp
użytkownik jest odpowiedzialny za usunięcie katalogu tymczasowego i jego zawartości po zakończeniu korzystania z niego.tempfile.TemporaryDirectory()
jako menedżera kontekstu, zostanie on usunięty.Może być trochę za późno, ale czy jest w tym coś złego?
import tempfile with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as tmpfile: temp_file_name = tmpfile.name f = gzip.open(temp_file_name ,'wb')
źródło
without creating actual file in Python
.tempfile.mktemp()
Zrób to.Ale pamiętaj, że jest przestarzały. Jednak nie utworzy pliku i jest to funkcja publiczna w pliku tymczasowym w porównaniu z użyciem
_get_candidate_names()
.Powodem, dla którego jest przestarzały, jest przerwa czasowa między wywołaniem tego a faktyczną próbą utworzenia pliku. Jednak w moim przypadku szansa na to jest niewielka i nawet gdyby się nie udała, to byłoby to do zaakceptowania. Ale to do Ciebie należy ocena dla Twojego przypadku.
źródło
tempfile.mktemp
dokumentacja). Więc to nie powinno być uważane za akceptowalne.os.path.join(tempfile.mkdtemp(), 'something')
Tam przynajmniej został utworzony katalog (i zakładam, że jest on Twoją własnością).Łącząc poprzednie odpowiedzi, moje rozwiązanie to:
def get_tempfile_name(some_id): return os.path.join(tempfile.gettempdir(), next(tempfile._get_candidate_names()) + "_" + some_id)
Ustaw
some_id
opcjonalne, jeśli nie są potrzebne.źródło
_get_candidate_names()
nie istnieje, można domyślnie użyć jakiegoś półlosowego generatora ciągów. Na przykład jakiś uuid.Jak powiedział Joachim Isaksson w komentarzach, jeśli otrzymujesz tylko nazwę, możesz mieć problemy, jeśli jakiś inny program użyje tej nazwy wcześniej niż twój program. Szanse są niewielkie, ale nie niemożliwe.
Dlatego bezpieczną rzeczą do zrobienia w tej sytuacji jest użycie pełnego konstruktora GzipFile (), który ma podpis
GzipFile( [filename[, mode[, compresslevel[, fileobj]]]])
. Możesz więc przekazać mu otwarty plikobj i, jeśli chcesz, również nazwę pliku. Szczegółowe informacje można znaleźć w dokumentacji gzip.źródło