Как добавить идентификатор к имени файла перед расширением?

У меня есть имя файла: name.ext

Я хочу сделать следующее:

name + id + '.' + ext for name, ext in filename.split()

или найти лучший способ взять имя файла и добавить случайную 7-значную строку до конца перед расширением.

Вот что я до сих пор:

def generate_id(size=7, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def append_id(filename):
    return (name + '_' + generate_id() + '.' + ext for name, ext in filename.split('.'))

но он рассматривает это как выражение генератора, что не является моим предполагаемым результатом.

Каким будет правильный способ записи функции append_id?

Ответ 1

Для этого в одну строку вы можете попробовать:

def append_id(filename):
    return "{0}_{2}.{1}".format(*filename.rsplit('.', 1) + [generate_id()])

Это не очень читабельно, хотя.

Большинство фреймворков предоставляют функции для работы с именами файлов, и Python не является исключением. Вы должны использовать os.path.splitex:

def append_id(filename):
  return "{0}_{2}{1}".format(*os.path.splitext(filename) + (generate_id(),))

Обратите внимание, что вторая версия нуждается в двух дополнительных модификациях:

  • splitext возвращает кортеж, а не список, поэтому нам нужно обернуть результат generate_id кортежем
  • splitext сохраняет точку, поэтому вам нужно удалить ее из строки формата

Тем не менее, я бы не стал иметь здесь единственного читателя - посмотрите следующий ответ для более удобочитаемых решений.

Ответ 2

Я бы предложил что-то простое и простое - используйте os.path.splitext, чтобы получить базовое имя и расширение, а после этого просто объединить все компоненты результата через str.format.

import os
import random
import string

def generate_id(size=7, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

def append_id(filename):
    name, ext = os.path.splitext(filename)
    return "{name}_{uid}{ext}".format(name=name, uid=generate_id(), ext=ext)

Некоторые тестовые файлы:

append_id("hello.txt")
append_id("hello")
append_id("multiple.dots.in.file")

Ответ 3

ваш ответ на один ответ со случайным поколением -

map(lambda x :x.split(".")[0] + "_" + hashlib.md5(("%.15f" % time.time())+"_"+''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(5))).hexdigest()[:7]+"."+x.split(".")[1], filenames)

здесь вы можете ввести filenames в список

просто использовал функцию генерации случайного id, которая занимает время и и случайную строку из 5 символов md5 и принимает первые 7 символов из этого.

Это не очень читаемо, но, поскольку вы попросили однострочное решение, я не мог придумать более сложный способ.

Ответ 4

Чтобы исправить ваш код generate_id, вам потребуется понимание списка.

def generate_id(size=7, chars=string.ascii_uppercase + string.digits):
    return '_' + ''.join([random.choice(chars) for _ in range(size)])

Используете ли вы python для переименования файлов? Вместо этого вы можете использовать программу командной строки, например pwgen.

mv $filename ${filename/%.ext/_$(pwgen 6 1).ext}

Если вы пишете файл из Python, рассмотрите возможность использования tempfile.NamedTemporaryFile с соответствующими параметрами. (delete = False, dir = ".", prefix = "...", suffix = "..." )

Ответ 5

def append_id(filename):
    parts = filename.split('.')
    return "".join(parts[:-1])+ '_' + generate_id() + '.' + parts[-1]

Ответ 6

Мне нужна была более простая версия добавления определенного суффикса к файлу .txt в программе на Python, т.е. мне нужно было добавить -VOC, -TEX, или -RAN к именам файлов. Например: имя файла -VOC.txt (для файла словаря), имя файла -TEX.txt (для простого текста или файла с кодировкой utf8) или имя файла -RAN.txt (для перевода файла TEX), Итак, я экспериментировал в Jupyter Notebook со следующим решением, и оно сработало, я получил желаемый результат:

filename = 'C:/Users/User/Desktop/test4.txt'

type(filename) # this is just to check the type of filename, which is a string
t = filename.rsplit('.' 1)
t # this gives me the list ['C:/Users/User/Desktop/test4.txt']

t[0] # this gives me 'C:/Users/User/Desktop/test4', without the '.txt'

# Now I can add the suffix I want to the file name, see below
t2 = t[0]+'-VOC'
t2 # this gives me 'C:/Users/User/Desktop/test4-VOC', which is the desired file name

Более конкретно, я применил вышеизложенное следующим образом:

def new_file():
    """
    Creates vocabulary file
    """
    global file_name

    input_file_name = filedialog.asksaveasfilename(initialdir="/",
    defaultextension='*.txt', filetypes=(("Text Documents", "*.txt"), ("all files", "*.*")))

    if input_file_name:
        file_name = input_file_name.rsplit('.', 1)[0]+'-VOC.txt' # notice this line
        with open(file_name, 'w', encoding='utf-8') as txt_file:
            txt_file.write(text_B.get('1.0', END))