2010-06-02 590 views
51

我有一個python web窗體有兩個選項 - 文件上傳textarea。我需要從每個值中取出值並將它們傳遞給另一個命令行程序。我可以很容易地通過文件上傳選項的文件名,但我不知道如何傳遞textarea的值。Python:如何創建一個唯一的文件名?

我想我需要做的是:

  1. 生成一個唯一的文件名
  2. 創建工作目錄
  3. 保存從文本區域傳遞到臨時值與該名稱的臨時文件文件
  4. 從我的Python模塊中執行命令行程序,並通過它的臨時文件的名稱

我不知道如何生成一個唯一的文件名。任何人都可以給我一些關於如何生成唯一文件名的提示嗎?任何算法,建議和代碼行讚賞。

謝謝你的關心

+1

我編輯你的問題,試圖使之更加清晰。讓我知道,如果我解釋錯誤的東西! – culix 2012-09-01 10:12:53

回答

82

我不認爲你的問題很清楚,但如果你需要的是一個唯一的文件名稱...

import uuid 

unique_filename = str(uuid.uuid4()) 
+0

我是否應該以更理解的方式再次編輯我的問題? – MysticCodes 2010-06-02 21:26:42

+0

對不起,我在Windows平臺上工作,所以不知道如何處理子流程 – MysticCodes 2010-06-03 10:04:00

+0

uuid似乎創建了一個很長的唯一字符串。我不認爲它有更好的文件名與長字符串和UUID,()在它。 – MysticCodes 2010-06-03 10:37:13

41

如果你想臨時文件在Python中,Python的標準庫中有一個名爲tempfile的模塊。如果要啓動其他程序以對文件進行操作,請使用tempfile.mkstemp()創建文件,使用os.fdopen()訪問mkstemp()爲您提供的文件描述符。

順便說一下,你說你正在運行Python程序中的命令?你應該幾乎肯定會使用subprocess模塊。

所以你可以很愉快地編寫代碼,看起來像:

import subprocess 
import tempfile 
import os 

(fd, filename) = tempfile.mkstemp() 
try: 
    tfile = os.fdopen(fd, "w") 
    tfile.write("Hello, world!\n") 
    tfile.close() 
    subprocess.Popen(["/bin/cat", filename]).wait()   
finally: 
    os.remove(filename) 

運行,你應該發現cat命令工作得很好,但臨時文件是在finally塊刪除。請注意,您已將刪除mkstemp()自動返回的臨時文件 - 庫無法知道您何時完成它! (編輯:我曾假設NamedTemporaryFile完成了你之後的工作,但那可能不是那麼方便 - 當臨時文件對象關閉時文件立即被刪除,並讓其他進程在你之前打開文件已關閉它將無法在某些平臺上運行,特別是Windows。對不起,我的部分失敗。)

+0

使用** NamedTemporaryFile **可能是他們想要的(除非他們希望它留在服務器上,然後他們可以使用「tempfile.NamedTemporaryFile(delete = False)」) – 2010-06-02 21:24:22

+0

我可以使該臨時文件名稱也是唯一的嗎?所以我以後可以在子進程完成時使用唯一名稱來保存它 – MysticCodes 2010-06-02 21:25:22

+0

@Terence Honles:我最初建議使用tempfile.NamedTemporaryFile(),但您無法真正使用它來創建其他進程可以在Windows上訪問的臨時文件。儘管如此,NamedTemporaryFile(delete = False)肯定是*更清晰的。 @ user343934:tempfile。mkstemp()在每次調用時都會給你一個唯一的名字 - 它隨機生成名稱,並使用操作系統工具(如果你想知道的話,可以使用O_EXCL)來避免衝突。 – 2010-06-02 21:33:45

2

我遇到了這個問題,我將爲那些可能正在尋找類似東西的人添加我的解決方案。我的方法是從ascii個字符中隨機創建一個文件名。這將是一個很好的概率獨一無二的。

from random import sample 
from string import digits, ascii_uppercase, ascii_lowercase 
from tempfile import gettempdir 
from os import path 

def rand_fname(suffix, length=8): 
    chars = ascii_lowercase + ascii_uppercase + digits 

    fname = path.join(gettempdir(), 'tmp-' 
       + ''.join(sample(chars, length)) + suffix) 

    return fname if not path.exists(fname) \ 
       else rand_fname(suffix, length) 
+1

這個問題的明顯答案與uuid包有關。但是,我的目標服務器有python 2.4,沒有uuid包和升級未經服務器所有者授權,因爲傳統軟件不兼容,所以這個答案適用於我。 – 2014-10-03 18:04:13

+1

我特別喜歡這個答案:可以很容易地調整項目規格。 – swdev 2015-04-29 02:41:33

+0

1)沒有理由在這裏使用遞歸,尤其是無界的。 2)'path.exists()'返回False時間與消費者實際打開文件的時間之間存在競爭條件。 – 2017-04-08 22:21:12

8

也許你需要獨特的臨時文件?

import tempfile 

f = tempfile.NamedTemporaryFile(mode='w+b', delete=False) 

print f.name 
f.close() 

f是打開的文件。 delete=False表示關閉後不要刪除文件。

+0

如果您不需要控制文件的名稱,這非常棒。 – hiwaylon 2014-10-28 18:34:13

+1

它應該是tmpfile.NamedTemporaryFile不只是NamedTemporaryFile。 – user1993015 2017-07-15 03:19:05

2

這可以使用獨特的函數在ufp.path模塊中完成。

import ufp.path 
ufp.path.unique('./test.ext') 

如果當前路徑存在'test.ext'文件。 ufp.path.unique函數返回'./test(d1).ext'。

見例如: Generate unique path at filepath or dirpath [Python]

+2

ufp是drupal的一部分嗎?不是標準模塊 – endolith 2015-08-07 23:09:05

2

可以使用datetime模塊

import datetime 
uniq_filename = str(datetime.datetime.now().date()) + '_' + str(datetime.datetime.now().time()).replace(':', '.') 

注: 我使用replace因爲冒號不是在許多操作系統允許文件。

就是這樣,每次只會給你一個唯一的文件名。

6

uuid模塊將是一個不錯的選擇,我更喜歡使用uuid.uuid4().hex隨機文件名,因爲它會返回沒有破折號一個十六進制字符串。

import uuid 
filename = uuid.uuid4().hex 

輸出應該是這樣的:

>>> import uuid 
>>> uuid.uuid() 
UUID('20818854-3564-415c-9edc-9262fbb54c82') 
>>> str(uuid.uuid4()) 
'f705a69a-8e98-442b-bd2e-9de010132dc4' 
>>> uuid.uuid4().hex 
'5ad02dfb08a04d889e3aa9545985e304' # <-- this one 
相關問題