Let's consider the below code:
fp=open('PR1.txt','r')
ch=fp.readlines()
print "%s" % (' '.join(ch))
print "\n"
fp.close()
Above code gives an error:
IOError: [Errno 2] No such file or directory: 'PR1.txt'
But when i am provididng its full location i.e;
fp=open('D:/PR1.txt','r')
then it is working properly...
IS it necessary to provide full location of file or there is some other way too?
No, it is not necessary, but you need to be certain you are running your script with the right working directory. Your script working directory is evidently not D:/.
In practice, it is better to only use relative paths if you are in full control of the working directory. You can get the current working directory with os.getcwd() and set it with os.chdir() but using absolute paths is usually better.
For paths relative to the current module or script, use the __file__ global to produce a directory name:
import os.path
here = os.path.dirname(os.path.absolute(__file__))
then use os.path.join() to make relative paths absolute in reference to here.
Related
I'm trying to use a program to read from a file with pi-digits. The program and the text file with the pi-digits are in the same directory, but i still get the error message :
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents.rstrip())
Traceback (most recent call last):
File "C:\Python\Python_Work\python_crash_course\files_and_exceptions\file_reader.py", line 1, in <module>
with open('pi_digits.txt') as file_object:
FileNotFoundError: [Errno 2] No such file or directory: 'pi_digits.txt'
I have looked for a solution but haven't found any.
I found a piece of code which supposedly shows me what the working directory is. I get an output that shows a directory that is 2 steps above the directory i have my programs and text file inside.
import os
cwd = os.getcwd() # Get the current working directory (cwd)
files = os.listdir(cwd) # Get all the files in that directory
print("Files in %r: %s" % (cwd, files))
So when i put the pi text document in the directory that the output is showing (>python_work), the program is working. When it does not work is when the text file is in ">files_and_exceptions" which is the same file the program itself is inside. My directory looks like this when it is not working:
>python_work
>python_crash_course
>files_and_exceptions
file_reader.py
pi_digits.txt
show_working_directory.py
And like this when it is working:
>python_work
pi_digits.txt
>python_crash_course
>files_and_exceptions
file_reader.py
show_working_directory.py
I'm new to python and really appreciate any help.
Thanks!
Relative path (one not starting with a leading /) is relative to some directory. In this case (and generally*), it's relative to the current working directory of the process.
In your case, given the information you've provided, for it would be "python_crash_course/files_and_exceptions/pi_digits.txt" in the first case as you appear to be running the script from python_work directory.
If you know the file to be in the same directory as the script itself, you could also say:
import os.path
...
os.path.join(os.path.dirname(__file__), "pi_digits.txt")
instead of "pi_digits.txt". Or the same using pathlib:
from pathlib import Path
...
Path(__file__).with_name("pi_digits.txt")
Actually unless you have a point to anchor to like the script itself, using relative filename / path (using absolute paths brings its own problems too) in the code directly is rather fragile and in that case getting it as a parameter of a function (and ultimately argument of CLI or script call in general) or alternatively reading it from standard input would be more robust.
* I would not make that an absolute statement, because there are situations and functions that can explicitly provide different anchor point (e.g. os.path.relpath or openat(2); or as another example a symlink target)
I am so new with python and pycharm and i got confuse!!
When I run my project in pycharm it gives me an error about not finding the path of my file. The physical file path is:
'../Project/BC/RequiredFiles/resources/a_reqs.csv'
My project working directory is "Project/BC" and the project running file (startApp.sh) is there too. but the .py file that wants to work with a_req.csv is inside the "RequiredFiles" folder. There is the following code in the .py file:
reqsfile = os.getcwd() + "/resources/a_reqs.csv"
it returns: '../Project/BC/resources/a_reqs.csv'
instead of: '../Project/BC/resources/RequiredFiles/a_reqs.csv'
while the .py file is in "RequiredFiles" the os.getcwd() must include it too. but it does not.
The problem is that i can not change the addressing code. because this code works in another IDE and other people who work with the code in other platform or OS do not have any problem. I am working in mac OS and if i am not mistaken the code works with windows!!
So, how can i tell Pycharm (in mac) to see and load "RequiredFiles" folder as the subfolder of my working directory!!!
os.getcwd returns the current working directory of the process (which may be the directory where startApp.sh is located or another one, depending on the PyCharm's run configuration setting, or, if you start the program from the command line, the directory in which you execute the command).
To make a path independent on the current working directory, you can take the directory where your Python file is located and build the path from it:
os.path.dirname(__file__) + "/resources/a_reqs.csv"
From your question what I see is:
reqsfile = os.getcwd() + "/resources/a_reqs.csv"
Which produces: "../Project/BC/resources/a_reqs.csv", whereas your desired output is
"../Project/BC/resources/RequiredFiles/a_reqs.csv". Since we know os.getcwd is returning "/Project/BC/", then to get your desired result you should be doing:
reqsfile = os.getcwd() + "/resources/RequiredFiles/a_reqs.csv"
But since you want the solution to work with or without the RequiredFiles subdirectory you could apply a conditional solution, ie something like:
import os.path
if os.path.exists(os.getcwd() + "/resources/RequiredFiles/a_reqs.csv"):
reqsfile = os.getcwd() + "/resources/RequiredFiles/a_reqs.csv"
else:
reqsfile = os.getcwd() + "/resources/a_reqs.csv"
This solution will set the reqsfile to the csv in the RequiredFiles directory if the directory exists, and thus will work for you. On the other-hand, if the RequiredFiles directory doesn't exist, it will default to the csv in /resources/.
Typically when groups collaborate on projects, the maintain the same file hierarchy so that these types of issues are avoided, so you might want to consider moving the csv from /RequiredFiles/ to /resources/.
I'm trying to understand how logfiles work with the Python 2 logging module.
I know that I can save the log output to a text file using something like:
logging.basicConfig(filename='example.log',level=logging.DEBUG)
It's not clear to me from the documentation on:
Whether or not absolute filename paths are valid
The proper syntax for specifying relative paths (assuming that ../example.log is valid).
If I execute this script from /home/bob, how do I specify that I want the logfile saved to the /tmp directory instead - using both absolute and relative paths?
Is logging.basicConfig(filename='../../tmp/example.log') valid?
Similarly, is logging.basicConfig(filename='/tmp/example.log') valid?
When stating just the filename, it would be written to the current directory.
Using Python IDLE you can check that as follows
>>> import logging
>>> logging.basicConfig(filename='relative.log')
>>> logging.info('test')
C:\Python27\relative.log
My working dir is Python27, and I have a file there named relative.log with my logged message.
When you change the file location to ../relative.log, I get a new file at the parent directory of Python27. So relative path does work for logging:
>>> import logging
>>> logging.basicConfig(filename='../relative.log')
>>> logging.info('test123')
C:\relative.log
And logging module also supports absolute path:
>>> logging.basicConfig(filename=r'c:\abs_path.log')
>>> logging.info('test')
C:\abs_path.log
It is always better to use absolute path, as explicit is better than implicit.
They are both valid. But relative paths (with ..) will select different files depending on the directory you are in when you run it.
So when you run logger.py in /home/user/projects/python and the filename is ../log.txt the file will be saved in /home/user/projects. On the other hand when you run the script in /home/user then log.txt will be saved in /home/.
Absolute paths always work and are more reliable. If you want a file in the current directory I recommend this approach:
basedir = os.path.abspath(os.path.dirname(__file__))
filename = os.path.join(basedir, 'file.txt')
If I try to rename files in a directory, for some reason I get an error.
I think the problem may be that I have not inserted the directory in the proper format ?
Additional info:
python 2 &
linux machine
OSError: [Errno 2] No such file or directory
Though it prints the directories content just fine. What am I doing wrong?
import os
for i in os.listdir("/home/fanna/Videos/strange"):
#print str(i)
os.rename(i, i[:-17])
os.rename() is expecting the full path to the file you want to rename. os.listdir only returns the filenames in the directory. Try this
import os
baseDir = "/home/fanna/Videos/strange/"
for i in os.listdir( baseDir ):
os.rename( baseDir + i, baseDir + i[:-17] )
Suppose there is a file /home/fanna/Videos/strange/name_of_some_video_file.avi, and you're running the script from /home/fanna.
i is name_of_some_video_file.avi (the name of the file, not including the full path to it). So when you run
os.rename(i, i[:-17])
you're saying
os.rename("name_of_some_video_file.avi", "name_of_some_video_file.avi"[:-17])
Python has no idea that these files came from /home/fanna/Videos/strange. It resolves them against the currrent working directory, so it's looking for /home/fanna/name_of_some_video_file.avi.
I'm a little late but the reason it happens is that os.listdir only lists the items inside that directory, but the working directory remains the location where the python script is located.
So to fix the issue add:
os.chdir(your_directory_here)
just before the for loop where your_directory_here is the directory you used for os.listdir.
How to remove path related problems in python?
For e.g. I have a module test.py inside a directory TEST
**test.py**
import os
file_path = os.getcwd() + '/../abc.txt'
f = open(file_path)
lines = f.readlines()
f.close
print lines
Now, when I execute the above program outside TEST directory, it gives me error:-
Traceback (most recent call last):
File "TEST/test.py", line 4, in ?
f = open(file_path)
IOError: [Errno 2] No such file or directory: 'abc.txt'
how to resolve this kind of problem. Basically this is just a small example that I have given up.
I am dealing with a huge problem of this kind.
I am using existing packages, which needs to be run only from that directory where it exists, how to resolve such kind of problems, so that I can run the program from anywhere I want.
Or able to deal with the above example either running inside TEST directory or outside TEST directory.
Any help.?
I think the easiest thing is to change the current working directory to the one of the script file:
import os
os.chdir(os.path.dirname(__file__))
This may cause problems, however, if the script is also working with files in the original working directory.
Your code is looking at the current working directory, and uses that as a basis for finding the files it needs. This is almost never a good idea, as you are now finding out.
The solution mentioned in the answer by Emil Vikström is a quickfix solution, but a more correct solution would be to not use current working directory as a startingpoint.
As mentioned in the other answer, __file__ isn't available in the interpreter, but it's an excellent solution for your code.
Rewrite your second line to something like this:
file_path = os.path.join(os.path.dirname(__file__), "..", "abc.txt")
This will take the directory the current file is in, join it first with .. and then with abc.txt, to create the path you want.
You should fix similar usage of os.getcwd() elsewhere in your code in the same way.