深入理解Python中allennlp.common.file_utils模块中的cached_path()函数的实现细节
allennlp.common.file_utils.cached_path()函数是在AllenNLP库中实现的一个工具函数,用于处理文件路径和URL。
该函数的作用是将文件的路径作为输入,返回一个经过处理后的路径。如果输入的路径是一个URL,函数会从URL中下载文件并返回本地文件的路径。如果输入的路径是本地文件路径,则函数直接返回该路径。
下面是cached_path()函数的详细实现细节:
def cached_path(url_or_filename: str, cache_dir: Optional[str] = None) -> str:
"""
Given something that might be a URL (or might be a local path), determine which.
If it's a URL, download the file and cache it, and return the path to the cached file.
If it's already a local path, make sure the file exists and then return the path.
"""
# Handle URLs
parsed = urlparse(url_or_filename)
if parsed.scheme in ('http', 'https', 's3'):
if cache_dir is None:
cache_dir = PYTORCH_PRETRAINED_BERT_CACHE
if cache_dir is not None:
os.makedirs(cache_dir, exist_ok=True)
# Use hashlib to get a unique file name for caching
# This is important in case the url ever changes
cache_filename = hashlib.md5(url_or_filename.encode('utf-8')).hexdigest()
cache_path = os.path.join(cache_dir, cache_filename)
# Download to cache if it doesn't exist
if not os.path.exists(cache_path):
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
temp_file.close()
logger.warning(
f'downloading {url_or_filename} to {temp_file.name}'
)
urllib.request.urlretrieve(url_or_filename, temp_file.name)
shutil.move(temp_file.name, cache_path)
logger.warning(f'creating metadata file for {cache_path}')
with open(cache_path + '.metadata', 'w') as metadata_file:
metadata_file.write(url_or_filename)
# Keep track of where we got this cached file from
with open(cache_path + '.cached_path', 'w') as path_file:
path_file.write(url_or_filename)
return cache_path
elif parsed.scheme == '':
if not os.path.exists(url_or_filename):
raise FileNotFoundError(f"file {url_or_filename} not found")
return url_or_filename
else:
raise ValueError(f"unable to parse {url_or_filename} as a URL or as} a local path")
首先,函数会分析输入路径的scheme(协议),如果是http、https或s3,则认为是一个URL。然后,函数会创建一个缓存目录(如果不存在)来存储这些下载的文件。函数会使用URL的哈希值生成一个 的文件名并将其拼接到缓存目录路径中。
接下来,函数会检查缓存目录是否存在该文件。如果不存在,函数会使用urllib.request.urlretrieve()方法下载文件到一个临时文件中,并将临时文件移动到缓存路径中。此外,函数还会创建一个.metadata文件,用于存储文件的原始URL。最后,函数会将该缓存文件的路径存储在.cached_path文件中,并返回该路径。
如果输入路径不是URL,则函数会检查该路径是否存在本地文件系统中。如果路径不存在,则会引发FileNotFoundError异常。如果路径存在,则直接返回该路径。
下面是使用cached_path()函数的一个例子:
from allennlp.common.file_utils import cached_path url_or_filename = 'https://example.com/example.txt' local_path = cached_path(url_or_filename) print(local_path)
在这个例子中,url_or_filename是一个URL。cached_path()函数会自动下载该URL指向的文件,并返回本地文件的路径。如果文件已经存在于缓存目录中,函数会直接返回缓存文件的路径。
需要注意的是,为了使cached_path()函数能正常工作,需要确保计算机上安装了必要的依赖库(如urllib和shutil)以及库函数引用PYTORCH_PRETRAINED_BERT_CACHE定义的缓存目录。此外,也需要确保计算机能够访问指定的URL。
