Reputation: 353
I am trying to play a wav file based on the character the user inputs. My project structure looks like:
mypkg/
|
| mypkg/
|
| __init__.py
| code.py
| sound/
|
| A.wav
| B.wav
| ...
|
| setup.py
I have added the following in setup.py
:
package_dir={'mypkg': 'mypkg'},
package_data={'mypkg': ['sound/*.wav']}
My code.py
looks like:
files = {
'A': 'sound/A.wav',
'B': 'sound/B.wav',
...
}
c = raw_input()
f = files.get(c, '?')
...playing the wave file code...
I know 'A': 'sound/A.wav',
is wrong. The problem is everything runs fine if I use the code as a script, but I get an IO error if I run setup.py
and then import this as a module in the console. Specifically:
IOError: [Errno 2] No such file or directory: 'sound/S.wav'
I know I have to use pkgutil.get_data()
but then how can I add the correct path to the files in my files
dictionary. What should my code.py
look like?
Upvotes: 4
Views: 2745
Reputation: 535
There is another way but working with data_fles
from setup.py
:
setup.py
setup(name='dcspy',
version=__version__,
...
data_files=[('dcspy_data', ['images/dcspy.ico'])],
...
When you pip install
will put data_files
here:
$ 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
you can access them in your package like:
root = tk.Tk()
root.iconbitmap(f'{sys.prefix}/dcspy_data/dcspy.ico')
Information: 2.7. Installing Additional Files
Upvotes: 2
Reputation: 90999
The issue is that, when you run a script, the current location of that script is where you run it from, assume you run the script from a totally different location using absolute path
, then the current location inside that script is the location you were in when you ran the script, not the location of the script.
For your example, in your code.py
, you need to get the location of that python file and then append the data file to that location, before using it.
To get the location of the python file being run, you can use __file__
, or the better - os.path.realpath(__file__)
, you need to understand that __file__
would give the complete path of the file, to extract the directory you have to use - os.path.dirname()
.
Then your code would look like -
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'),
...
}
Upvotes: 4