我有一个文件名:name.ext
我想做以下事情:
name + id + '.' + ext for name, ext in filename.split()
Run Code Online (Sandbox Code Playgroud)
或者找到一种更好的方法来获取文件名并在扩展名之前添加一个随机的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('.'))
Run Code Online (Sandbox Code Playgroud)
但它将它视为生成器表达式,这不是我想要的结果.
编写append_id函数的正确方法是什么?
Łuk*_*ski 22
我建议简单明了 - 用于os.path.splitext检索basename和extension,然后通过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)
Run Code Online (Sandbox Code Playgroud)
一些测试用例:
append_id("hello.txt")
append_id("hello")
append_id("multiple.dots.in.file")
Run Code Online (Sandbox Code Playgroud)
Bar*_*zKP 15
要在一行中执行此操作,您可以尝试:
def append_id(filename):
return "{0}_{2}.{1}".format(*filename.rsplit('.', 1) + [generate_id()])
Run Code Online (Sandbox Code Playgroud)
但它不是很易读.
大多数框架都提供了处理文件名的功能,Python也不例外.你应该使用os.path.splitex:
def append_id(filename):
return "{0}_{2}{1}".format(*os.path.splitext(filename) + (generate_id(),))
Run Code Online (Sandbox Code Playgroud)
尽管如此,我仍然不会在这里找到一个oneliner - 请参阅下一个答案以获得更具可读性的解决方案.
Tom*_*koo 11
从 Python 3.4 开始,处理路径的好工具是pathlib. 这将路径视为对象而不是字符串并提供强大的接口。
从 Python 3.9 开始,with_stem添加了一个新方法 - ,因此您的函数可以是:
from pathlib import Path
def append_id(filename):
path = Path(filename)
return path.with_stem(f"{path.stem}_{generate_id()}")
Run Code Online (Sandbox Code Playgroud)
对于旧版本,您仍然可以使用该with_name方法:
from pathlib import Path
def append_id(filename):
path = Path(filename)
return path.with_name(f"{path.stem}_{generate_id()}{path.suffix}")
Run Code Online (Sandbox Code Playgroud)
这些函数是通用的,也适用于完整/相对路径,而不仅仅是文件名:
>>> append_id("sample.text")
PosixPath('sample_PBMQBFD.text')
>>> append_id("/a/b/c/sample.text")
PosixPath('/a/b/c/sample_UMTYXCP.text')
Run Code Online (Sandbox Code Playgroud)
请注意,将Path返回特定于平台的对象。您始终可以使用以下命令将其转换回字符串str():
>>> str(append_id("/a/b/c/sample.text"))
'/a/b/c/sample_O1LPTEC.text'
Run Code Online (Sandbox Code Playgroud)