Home > Mobile >  How to extract the full path from a file while using the "with" statement?
How to extract the full path from a file while using the "with" statement?

Time:07-03

I'm trying, just for fun, to understand if I can extract the full path of my file while using the with statement (python 3.8) I have this simple code:

with open('tmp.txt', 'r') as file:
   print(os.path.basename(file))

But I keep getting an error that it's not a suitable type format. I've been trying also with the relpath, abspath, and so on. It says that the input should be a string, but even after casting it into string, I'm getting something that I can't manipulate. Perhaps there isn't an actual way to extract that full path name, but I think there is. I just can't find it, yet.

CodePudding user response:

You could try:

import os

with open("tmp.txt", "r") as file_handle:
   print(os.path.abspath(file_handle.name))

CodePudding user response:

The functions in os.path accept strings or path-like objects. You are attempting to pass in a file instead. There are lots of reasons the types aren't interchangable.

Since you opened the file for text reading, file is an instance of io.TextIOWrapper. This class is just an interface that provides text encoding and decoding for some underlying data. It is not associated with a path in general: the underlying stream can be a file on disk, but also a pipe, a network socket, or an in-memory buffer (like io.StringIO). None of the latter are associated with a path or filename in the way that you are thinking, even though you would interface with them as through normal file objects.

If your file-like is an instance of io.FileIO, it will have a name attribute to keep track of this information for you. Other sources of data will not. Since the example in your question uses FileIO, you can do

with open('tmp.txt', 'r') as file:
   print(os.path.abspath(file.name))

The full file path is given by os.path.abspath.

That being said, since file objects don't generally care about file names, it is probably better for you to keep track of that info yourself, in case one day you decide to use something else as input. Python 3.8 allows you to do this without changing your line count using the walrus operator:

with open((filename := 'tmp.txt'), 'r') as file:
   print(os.path.abspath(filename))
  • Related