Python中等同于Class.getResource()的是什么?

2 投票
3 回答
1119 浏览
提问于 2025-04-17 07:57

在Java中,如果我想读取一个包含我算法所需资源数据的文件,我该怎么做才能正确引用路径呢?

澄清一下,我想理解在Python的世界里,如何将数据和代码打包在一个模块里。

举个例子,我可能在写一些代码,目的是分析一个字符串,试图判断这个文本是用什么语言写的。为了实现这个功能,我需要一个包含语言模型数据的文件。

所以当我的代码被调用时,我希望能够加载一个(或多个)与模块一起打包的文件。我不太清楚在Python中该怎么做。

谢谢大家。

3 个回答

0

对于不太了解的Python爱好者来说,Java中的Class.getResource的行为大致是这样的:提供的文件名(除非它已经是一个绝对路径)会根据类的包名转换成一个相对路径(因为类文件的目录路径通常和类的“包”声明是一致的)。然后,用于加载这个类的ClassLoader会根据自己的逻辑把这个路径字符串转换成一个URL对象,这个对象可以表示文件名、网络位置等。

Python和Java不一样,所以我们需要做一些近似处理,并理解提问者的意图。

Python的类并不明确地放在包里,虽然你可以通过把它们放在带有__init__.py文件的文件夹中来创建包。

Python的标准库里没有类似URL类的东西;虽然有很多支持连接互联网的功能,但通常你只需要用字符串来表示URL(和文件名),并适当地格式化它们。这可以说是一个错失的机会(虽然你可以自己写一个包装器,但可能会漏掉很多特殊情况和有用的功能)。总之,在Java的正常情况下,你并不指望通过这个过程得到一个网页URL。

Python有一个“工作目录”的概念,这个目录取决于Python进程是如何启动的。文件路径不一定是相对于“主类”(其实是“主模块”,因为Python不要求你把所有东西都放在一个类里)所在的目录。

所以你真正想要的,可能是获取与类对应的源文件的绝对路径。但这也不太可能实现。问题在于:给定一个类,你可以得到它来自的模块名,然后查找这个名字以获取实际的模块对象,再从模块对象中获取加载该模块时的文件名。然而,这个文件名是相对于模块加载时的工作目录的,而这个信息并没有被记录下来。如果工作目录在那之后发生了变化(通过os.chdir),那就没办法了。

请尽量更清楚地说明你真正想要做的事情。

0

我觉得你在找的是 imp.load_source 这个东西:

import imp

module = imp.load_source('ModuleName', '/path/of/the/file.py')
module.FooBar()
2

我觉得你可能在找 pkgutil.get_data()。它的说明是这样的:

pkgutil.get_data(package, resource)

从一个包中获取资源。

这个函数是 PEP 302 加载器的一个封装,用于获取数据。你需要提供一个包的名字,格式要像这样:foo.bar。资源的参数应该是相对文件名,用 / 作为路径分隔符。你不能使用父目录名 ..,也不能用以 / 开头的绝对路径。

这个函数会返回一个二进制字符串,也就是你指定的资源的内容。

对于已经在文件系统中导入的包,这个函数大致相当于:

d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()

如果找不到这个包,或者无法加载,或者它使用的 PEP 302 加载器不支持 get_data(),那么就会返回 None。

撰写回答