Cách tốt nhất để tạo tên tệp ngẫu nhiên bằng Python


95

Trong Python, đâu là cách tốt hoặc cách tốt nhất để tạo một số văn bản ngẫu nhiên để thêm trước vào tệp (tên) mà tôi đang lưu vào máy chủ, chỉ để đảm bảo rằng nó không ghi đè. Cảm ơn bạn!

Câu trả lời:


109

Python có các phương tiện để tạo tên tệp tạm thời, xem http://docs.python.org/library/tempfile.html . Ví dụ:

In [4]: import tempfile

Mỗi lệnh gọi đến tempfile.NamedTemporaryFile()dẫn đến một tệp tạm thời khác nhau và tên của nó có thể được truy cập bằng .namethuộc tính, ví dụ:

In [5]: tf = tempfile.NamedTemporaryFile()
In [6]: tf.name
Out[6]: 'c:\\blabla\\locals~1\\temp\\tmptecp3i'

In [7]: tf = tempfile.NamedTemporaryFile()
In [8]: tf.name
Out[8]: 'c:\\blabla\\locals~1\\temp\\tmpr8vvme'

Khi bạn có tên tệp duy nhất, nó có thể được sử dụng như bất kỳ tệp thông thường nào. Lưu ý : Theo mặc định, tệp sẽ bị xóa khi đóng. Tuy nhiên, nếu deletetham số là False, tệp sẽ không tự động bị xóa.

Bộ thông số đầy đủ:

tempfile.NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None[, delete=True]]]]]])

cũng có thể chỉ định tiền tố cho tệp tạm thời (là một trong các tham số khác nhau có thể được cung cấp trong quá trình tạo tệp):

In [9]: tf = tempfile.NamedTemporaryFile(prefix="zz")
In [10]: tf.name
Out[10]: 'c:\\blabla\\locals~1\\temp\\zzrc3pzk'

Có thể tìm thấy các ví dụ bổ sung để làm việc với các tệp tạm thời tại đây


1
Những tệp đó có bị xóa vào lần sau khi tôi khởi động lại máy của mình không?
HelloWorld

14
Vấn đề với giải pháp này là nó không chỉ tạo ra một tên tệp mà còn tạo ra một tệp đã được mở. Nếu bạn cần một tên tệp tạm thời cho một tệp mới, chưa tồn tại (ví dụ: để sử dụng làm đầu ra của lệnh os), điều này sẽ không thực hiện được. Trong trường hợp đó, bạn có thể làm điều gì đó như str (uuid.uuid4 ()).
Luca

@Luca Cảm ơn bạn đã nhận xét bổ sung, rất hữu ích và ghi chú để tham khảo trong tương lai. Tuy nhiên, OP đã nói rõ rằng anh ấy / cô ấy muốn lưu một tệp, do đó cần phải mở nó, vì vậy giải pháp này cung cấp cho điều đó.
Levon

Nó phụ thuộc. Có lẽ anh ta cần tên để tạo một cuộc gọi máy chủ thích hợp. Không chắc. Ở mức nào đó, câu trả lời của bạn chắc chắn là trường hợp phổ biến hơn.
Luca

104

Bạn có thể sử dụng mô-đun UUID để tạo một chuỗi ngẫu nhiên:

import uuid
filename = str(uuid.uuid4())

Đây là một lựa chọn hợp lệ, vì trình tạo UUID cực kỳ khó có khả năng tạo ra một số nhận dạng trùng lặp (trong trường hợp này là tên tệp):

Chỉ sau khi tạo ra 1 tỷ UUID mỗi giây trong 100 năm tới, xác suất chỉ tạo ra một bản sao sẽ là khoảng 50%. Xác suất của một bản sao sẽ là khoảng 50% nếu mỗi người trên trái đất sở hữu 600 triệu UUID.


16
điều này cũng rất hữu ích khi bạn muốn một tên tệp duy nhất, nhưng chưa muốn nó được tạo.
GS Falken

14
Hoặc sử dụng uuid.uuid4().hexđể lấy một chuỗi hex không có dấu gạch ngang ( -).
Rockallite

17

một cách tiếp cận phổ biến là thêm dấu thời gian làm tiền tố / hậu tố vào tên tệp để có một số mối quan hệ tạm thời với tệp. Nếu bạn cần sự độc đáo hơn, bạn vẫn có thể thêm một chuỗi ngẫu nhiên vào chuỗi này.

import datetime
basename = "mylogfile"
suffix = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
filename = "_".join([basename, suffix]) # e.g. 'mylogfile_120508_171442'

4
Trong môi trường đa luồng, có thể có một điều kiện chạy đua liên quan đến trình tự 1. Test if file exists, 2. create file.Nếu một quy trình khác làm gián đoạn quá trình của bạn giữa các bước 1 và 2 và tạo tệp, khi mã của bạn tiếp tục, nó sẽ ghi đè lên tệp của quy trình khác.
Li-aung Yip

@ Li-aungYip Ngoài ra cũng có thể sử dụng chuỗi ký tự ngẫu nhiên 6-8 (trong trường hợp 2 tệp được tạo trong cùng một giây).
bobobobo

@bobobobo: Hoặc bạn có thể sử dụng tempfilemô-đun để xử lý việc này cho bạn. :)
Li-aung Yip

Tôi khuyên bạn nên thêm micro giây tức là...strftime("%y%m%d_%H%M%S%f")
AstraSerg

8

OP đã yêu cầu tạo tên tệp ngẫu nhiên không phải tệp ngẫu nhiên . Thời gian và UUID có thể va chạm. Nếu bạn đang làm việc trên một máy (không phải hệ thống tệp được chia sẻ) và quy trình / luồng của bạn sẽ không chạy trên chính nó, hãy sử dụng os.getpid () để lấy PID của riêng bạn và sử dụng nó như một phần tử của một tên tệp duy nhất. Các quy trình khác rõ ràng sẽ không nhận được cùng một PID. Nếu bạn đang chạy đa luồng, hãy lấy id luồng. Nếu bạn có các khía cạnh khác của mã, trong đó một luồng hoặc quy trình có thể tạo ra nhiều tệp mẫu khác nhau, bạn có thể cần sử dụng một kỹ thuật khác. Chỉ mục cuộn có thể hoạt động (nếu bạn không giữ chúng quá lâu hoặc sử dụng quá nhiều tệp, bạn sẽ lo lắng về việc cuộn qua). Giữ một mã băm / chỉ mục chung cho các tệp "hoạt động" sẽ là đủ trong trường hợp đó.

Rất tiếc cho lời giải thích dài dòng, nhưng nó phụ thuộc vào cách sử dụng chính xác của bạn.


8

Nếu bạn không cần đường dẫn tệp, nhưng chỉ chuỗi ngẫu nhiên có độ dài được xác định trước, bạn có thể sử dụng một cái gì đó như thế này.

>>> import random
>>> import string

>>> file_name = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
>>> file_name
'ytrvmyhkaxlfaugx'

7

Nếu bạn muốn giữ lại tên tệp gốc như một phần của tên tệp mới, các tiền tố duy nhất có độ dài đồng nhất có thể được tạo bằng cách sử dụng hàm băm MD5 của thời điểm hiện tại:

from hashlib import md5
from time import localtime

def add_prefix(filename):
    prefix = md5(str(localtime()).encode('utf-8')).hexdigest()
    return f"{prefix}_{filename}"

Các lệnh gọi tới add_prefix ('style.css') tạo ra chuỗi như:

a38ff35794ae366e442a0606e67035ba_style.css
7a5f8289323b0ebfdbc7c840ad3cb67b_style.css

1
Để tránh: Unicode-đối tượng phải được mã hóa trước khi băm Tôi đã thay đổi để md5 (str (localtime ()) mã hóa ( 'utf-8').) Hexdigest ().
PhoebeB

1
Lưu ý rằng một hàm băm của bất kỳ loại dữ liệu nào (bao gồm cả dấu thời gian) không đảm bảo tính duy nhất của chính nó (bất kỳ hơn một chuỗi byte được chọn ngẫu nhiên nào).
Peter O.

1

Thêm hai xu của tôi ở đây:

In [19]: tempfile.mkstemp('.png', 'bingo', '/tmp')[1]
Out[19]: '/tmp/bingoy6s3_k.png'

Theo tài liệu python cho tempfile.mkstemp, nó tạo tệp tạm thời theo cách an toàn nhất có thể. Xin lưu ý rằng tệp sẽ tồn tại sau cuộc gọi này:

In [20]: os.path.exists(tempfile.mkstemp('.png', 'bingo', '/tmp')[1])
Out[20]: True

1

Cá nhân tôi thích để văn bản của mình không chỉ ngẫu nhiên / độc đáo mà còn đẹp nữa, đó là lý do tại sao tôi thích hashids lib, tạo ra văn bản ngẫu nhiên trông đẹp mắt từ các số nguyên. Có thể cài đặt thông qua

pip install hashids

Đoạn trích:

import hashids
hashids = hashids.Hashids(salt="this is my salt", )
print hashids.encode(1, 2, 3)
>>> laHquq

Mô tả ngắn:

Hashids là một thư viện mã nguồn mở nhỏ tạo ra các id ngắn, duy nhất, không tuần tự từ các số.


0
>>> import random
>>> import string    
>>> alias = ''.join(random.choice(string.ascii_letters) for _ in range(16))
>>> alias
'WrVkPmjeSOgTmCRG'

Bạn có thể thay đổi 'string.ascii_letters' thành bất kỳ định dạng chuỗi nào bạn muốn để tạo bất kỳ văn bản nào khác, ví dụ: di động NO, ID ... nhập mô tả hình ảnh ở đây


0
import uuid
   imageName = '{}{:-%Y%m%d%H%M%S}.jpeg'.format(str(uuid.uuid4().hex), datetime.now())

1
Mặc dù mã này có thể giải quyết câu hỏi, bao gồm giải thích về cách thức và lý do tại sao điều này giải quyết vấn đề sẽ thực sự giúp cải thiện chất lượng bài đăng của bạn và có thể dẫn đến nhiều phiếu bầu hơn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ người hỏi bây giờ. Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những giới hạn và giả định áp dụng.
Богдан Опир

-1

Bạn có thể sử dụng gói ngẫu nhiên:

import random
file = random.random()

file = str (random.random ())
anajem

Điều này tạo ra các số ngẫu nhiên, không phải là một văn bản ngẫu nhiên.
user1767754
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.