从 python 包中访问数据文件
Access data files from within a python package
我正在尝试根据用户输入的字符播放 wav 文件。
我的项目结构如下:
mypkg/
|
| mypkg/
|
| __init__.py
| code.py
| sound/
|
| A.wav
| B.wav
| ...
|
| setup.py
我在setup.py
中添加了以下内容:
package_dir={'mypkg': 'mypkg'},
package_data={'mypkg': ['sound/*.wav']}
我的 code.py
看起来像:
files = {
'A': 'sound/A.wav',
'B': 'sound/B.wav',
...
}
c = raw_input()
f = files.get(c, '?')
...playing the wave file code...
我知道'A': 'sound/A.wav',
是错的。问题是如果我将代码用作脚本,一切 运行 都很好,但如果我 运行 setup.py
然后将其作为模块导入控制台,我会收到 IO 错误。具体来说:
IOError: [Errno 2] No such file or directory: 'sound/S.wav'
我知道我必须使用 pkgutil.get_data()
但是我怎样才能将正确的路径添加到我的 files
字典中的文件。我的 code.py
应该是什么样子?
问题是,当您 运行 一个脚本时,该脚本的当前位置就是您 运行 它的来源,假设您 运行 来自一个完全不同的脚本使用 absolute path
的位置,则该脚本中的当前位置是您 运行 脚本时所在的位置,而不是脚本的位置。
对于您的示例,在您的 code.py
中,您需要获取该 python 文件的位置,然后将数据文件附加到该位置,然后再使用它。
要获取 python 文件的位置 运行,您可以使用 __file__
或更好的 - os.path.realpath(__file__)
,您需要了解 __file__
将给出文件的完整路径,以提取您必须使用的目录 - os.path.dirname()
.
那么你的代码看起来像 -
pt = os.path.dirname(os.path.realpath(__file__))
files = {
'A': os.path.join(pt, 'sound/A.wav'),
'B': os.path.join(pt, 'sound/B.wav'),
...
}
还有另一种方法,但是使用 setup.py
中的 data_fles
:
setup.py
setup(name='dcspy',
version=__version__,
...
data_files=[('dcspy_data', ['images/dcspy.ico'])],
...
当您 pip install
将 data_files
放在这里时:
$ pip uninstall dcspy
Found existing installation: dcspy 1.1.2
Uninstalling dcspy-1.1.2:
Would remove:
d:\python38\dcspy_data\dcspy.ico
d:\python38\lib\site-packages\dcspy-1.1.2.dist-info\*
d:\python38\lib\site-packages\dcspy\*
d:\python38\scripts\dcspy.exe
Proceed (y/n)? y
您可以在您的包裹中访问它们,例如:
root = tk.Tk()
root.iconbitmap(f'{sys.prefix}/dcspy_data/dcspy.ico')
我正在尝试根据用户输入的字符播放 wav 文件。 我的项目结构如下:
mypkg/
|
| mypkg/
|
| __init__.py
| code.py
| sound/
|
| A.wav
| B.wav
| ...
|
| setup.py
我在setup.py
中添加了以下内容:
package_dir={'mypkg': 'mypkg'},
package_data={'mypkg': ['sound/*.wav']}
我的 code.py
看起来像:
files = {
'A': 'sound/A.wav',
'B': 'sound/B.wav',
...
}
c = raw_input()
f = files.get(c, '?')
...playing the wave file code...
我知道'A': 'sound/A.wav',
是错的。问题是如果我将代码用作脚本,一切 运行 都很好,但如果我 运行 setup.py
然后将其作为模块导入控制台,我会收到 IO 错误。具体来说:
IOError: [Errno 2] No such file or directory: 'sound/S.wav'
我知道我必须使用 pkgutil.get_data()
但是我怎样才能将正确的路径添加到我的 files
字典中的文件。我的 code.py
应该是什么样子?
问题是,当您 运行 一个脚本时,该脚本的当前位置就是您 运行 它的来源,假设您 运行 来自一个完全不同的脚本使用 absolute path
的位置,则该脚本中的当前位置是您 运行 脚本时所在的位置,而不是脚本的位置。
对于您的示例,在您的 code.py
中,您需要获取该 python 文件的位置,然后将数据文件附加到该位置,然后再使用它。
要获取 python 文件的位置 运行,您可以使用 __file__
或更好的 - os.path.realpath(__file__)
,您需要了解 __file__
将给出文件的完整路径,以提取您必须使用的目录 - os.path.dirname()
.
那么你的代码看起来像 -
pt = os.path.dirname(os.path.realpath(__file__))
files = {
'A': os.path.join(pt, 'sound/A.wav'),
'B': os.path.join(pt, 'sound/B.wav'),
...
}
还有另一种方法,但是使用 setup.py
中的 data_fles
:
setup.py
setup(name='dcspy',
version=__version__,
...
data_files=[('dcspy_data', ['images/dcspy.ico'])],
...
当您 pip install
将 data_files
放在这里时:
$ pip uninstall dcspy
Found existing installation: dcspy 1.1.2
Uninstalling dcspy-1.1.2:
Would remove:
d:\python38\dcspy_data\dcspy.ico
d:\python38\lib\site-packages\dcspy-1.1.2.dist-info\*
d:\python38\lib\site-packages\dcspy\*
d:\python38\scripts\dcspy.exe
Proceed (y/n)? y
您可以在您的包裹中访问它们,例如:
root = tk.Tk()
root.iconbitmap(f'{sys.prefix}/dcspy_data/dcspy.ico')