I am trying to use a for loop to copy files in different source folders into the same destination folder. I like to use literal representations to avoid issues with multiple backslashes in the file paths. I could not find the proper way to get a literal representation of a variable. Any tip would be appreciated. The code is below:
import shutil
destination_folder=DF
for i in range (1,3):
new_folder='folder_'+str(i)
new_path=os.path.join('C:\foo', new_folder, file_to_copy)
source_file= r(new_path) #WRONG
destination= r(destination_folder) #WRONG
shutil.copy(source_file, destination)
r
is not a function that applies to string objects, it's a modifier that applies to string literals. It changes how the literal gets interpreted as a value. But once it's done, the value is just a plain old string value. In particular:
>>> a = '\n'
>>> b = '''
... '''
>>> a == b
True
So, if a
and b
are the same value, how can Python possibly know that you want to turn it into r'\n'
?
For that matter, imagine this:
>>> c = sys.stdin.readline()
>>> c == a
True
Or this:
>>> d = chr(10)
>>> d == a
You can't go back and re-interpret the string literal as a raw string in any of these other cases—in b
it would be unchanged, and in c
and d
there was no string literal in the first place.
If you want to escape all special characters in a string value, without caring where they came from, you can do that by asking Python to escape the string. For example:
>>> e = a.encode('unicode-escape').decode('ascii')
But you definitely don't want to do that for constructing filenames to pass to the shutil.copy
function.
If you have a string literal in your code, and you want it to be treated as a raw string literal, just write it as a raw string literal. So:
new_path=os.path.join(r'C:\foo', new_folder, file_to_copy)
source_file= new_path
destination= destination_folder
You could instead manually escape the backslash in your literal, or use forward slashes instead of backslashes, etc. But those are all things you do to the literal before it gets evaluated by Python, not to the string after the fact.