0

I want to be able to use backslashes in string literals, for example: C:\file.txt

I was expecting to be able to escape the backslash with "\\", but for some weird reason that produces two backslashes instead of one. Why?

MVCE:

with open("temp.csv", 'w', encoding='utf-8') as f:
    d = { "filepath" : "C:\\bahä.txt" }
    s = json.dumps(d, ensure_ascii=False)
    f.write(s)

Expected behavior: file content should be C:\bahä.txt

Actual behavior: file content is C:\\bahä.txt

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
tiko93
  • 31
  • 6
  • 1
    can you show some code? – teoML Dec 18 '19 at 11:25
  • The code in OP `"\\"` produces the behavior described. – tiko93 Dec 18 '19 at 11:26
  • Does this answer your question? [How to print a single backslash?](https://stackoverflow.com/questions/19095796/how-to-print-a-single-backslash) – teoML Dec 18 '19 at 11:28
  • That is the `raw string`. It will only show `'\\'` in REPL, if you print: `print("\\")` it will produce single `\` – Sayandip Dutta Dec 18 '19 at 11:28
  • @t_e_o No the link does not answer the question, because it contains literally the same code that I pasted in OP and also in the comment, `"\\"` which I already explained does not behave as expected. – tiko93 Dec 18 '19 at 11:31
  • @SayandipDutta I need to write the strings to a file, and when I use `"\\"` I end up with double backslashes in the file instead of single backslashes. – tiko93 Dec 18 '19 at 11:31
  • 3
    @tiko93 please post a__PROPER__ [mcve] showing __exactly__ how you define the variable, how you use it, and how you read the result showing that you ended up with a double backslash. We must be able to __exactly__ reproduce the issue just by running your script. Just stating that '"\\" produces the behavior described' is not enough. – bruno desthuilliers Dec 18 '19 at 11:35
  • Wtf seriously? This is the minimal reproducible example. – tiko93 Dec 18 '19 at 11:36
  • 1
    This is not. Try adding how are you trying to use it. Like you are saying you want to write into a file, so are you trying: `with open(,'w') as f: f.write('\\')`. Or are you struggling to specify the path, that needs `\` in it? – Sayandip Dutta Dec 18 '19 at 11:40
  • 2
    @tiko93 no, it isn't. When I run this `s = "\\"; print(s)`, I do get a single backslah, as it should. If it weren't the case, this would be a major bug in Python. How likely do you think it is that such a bug would have made it to a release ? – bruno desthuilliers Dec 18 '19 at 11:41
  • @brunodesthuilliers You get a single backslash because `print` does something to the string other than displays it in raw form. But I'm not printing to stdout, I'm writing to a file, and the str contains two backslashes, and two backslashes are written to the file. – tiko93 Dec 18 '19 at 11:45
  • I added MVCE to OP now. – tiko93 Dec 18 '19 at 11:46
  • How are you viewing the contents of the file? Which text editor are you using? – RedX Dec 18 '19 at 11:46
  • @RedX It's not an issue with the text editor. – tiko93 Dec 18 '19 at 11:51
  • @tiko93 I pretty well know why it prints a single backslash, and that's not "because print does something to the string". – bruno desthuilliers Dec 18 '19 at 11:53
  • @brunodesthuilliers I'm not exactly sure what you are arguing here. It sounds like you don't believe the MVCE I posted behaves as I described. Why don't you just run the code that I edited into OP and see that it does behave as I described? – tiko93 Dec 18 '19 at 11:57
  • I can verify that two backslashes are printed to the file. It is a perfectly fine MVCE. It is perhaps OS-specific what happens when you run the code. – John Coleman Dec 18 '19 at 11:58
  • @tiko93 The second backslash in your example is here for the same reasons as it's in the raw (internal) representation of the python string - using backslashes as escape char is not specific to python. If you unserialize the json and print _only_ the filename value, you'll find out it's ok. – bruno desthuilliers Dec 18 '19 at 12:01
  • @brunodesthuilliers So you now agree with me that the raw representation contains the double backslash and the print "does something to it", even though you earlier laughed at this remark? – tiko93 Dec 18 '19 at 12:11
  • I never said the raw representation didn't contained a double backslash - of course it does -, what I said is that `print()` shows you the REAL string, not it's internal representation. If you were to write `"\\"` _directly_ in a file, you'd get the expected result. I guess we don't have the same definition of "do something to a string". – bruno desthuilliers Dec 18 '19 at 12:20

2 Answers2

4

In JSON you need to escape the backslash. That is why when you dump your string it keeps the backslash escaped. if you have only one backslash, e.g. "C:\bahä.txt" then \b is backspace (i.e. if it wasn't b after the backslash to produce valid escape sequence it would be invalid json). you can test and see that

import json
with open("temp.json", 'w', encoding='utf-8') as f:
    d = {"filepath":"\ "}
    s = json.dumps(d, ensure_ascii=False)
    f.write(s)

or

import json
with open("temp.json", 'w', encoding='utf-8') as f:
    d = { "filepath" : r"\b" }
    s = json.dumps(d, ensure_ascii=False)
    f.write(s)

both will again produce escaped backslash (i.e. \\) in the resulting json.

https://stackoverflow.com/a/19176131/4046632

As a side note - you are writing json, use the proper extension - .json, not .csv

buran
  • 13,682
  • 10
  • 36
  • 61
3

The problem here is that you are serializing to JSON.

In Json some special characters are serialized with a \ prepended: https://stackoverflow.com/a/19176131/551045

So a \ is always \\ in proper serialized JSON data.

If you change your code to:

with open("temp.csv", 'w', encoding='utf-8') as f:
    d = "C:\\bah.txt"
    f.write(d)

You'll see that your file will only contain one slash.

BTW that's why we always ask for MVCE even if the problem seems "trivial".

RedX
  • 14,749
  • 1
  • 53
  • 76
  • The instructions for MVCE on this site are that it's supposed to be the minimal possible example which demonstrates the problem. In my case, I was able to run the following code in Jupyter notebook: `"\\"` and that code produced me output `"\\"` which was not the expected output. So the MVCE that I posted earlier was the minimal possible example. In any case thank you for the answer! – tiko93 Dec 18 '19 at 12:01
  • 2
    Yes the first example you posted worked fine and thank you for posting it. The very first version of your question had no such code snippet and that's when we asked you to post one. – RedX Dec 18 '19 at 12:02
  • @tiko93: but you are still missing an example of actual and expected outputs. Its not just the code its the input data and the outputs. – quamrana Dec 18 '19 at 12:05
  • No I mean the very first version of OP that I posted contained this code example: `"\\"`. That was the minimal possible example. Later people asked for an expanded code example, which you are referring to now. – tiko93 Dec 18 '19 at 12:06
  • @quamrana No, I had the expected and actual outputs in the very first version of OP. The code is `"\\"`, the expected output is a single backslash `"\"` and the actual output is a double backslash `"\\"`. These were all in the original version of OP. – tiko93 Dec 18 '19 at 12:07
  • I really don't understand the reaction from people here to be honest. I very clearly and demonstrably provided a MVCE and that is a verifiable fact. You could say that the MVCE was too minimal in this case, but don't claim that the MVCE did not exist. – tiko93 Dec 18 '19 at 12:09
  • No, the first post contained data only. The second version (the best so far) seemed to have everything. The current (third) is missing expected and actual outputs. – quamrana Dec 18 '19 at 12:10
  • @quamrana All versions of this post have had expected and actual outputs described. See here: "I was expecting to be able to escape the backslash with `"\\"`, but for some weird reason that produces two backslashes instead of one." – tiko93 Dec 18 '19 at 12:13
  • Yes, descriptions can be misinterpreted. Its better to have actual code, actual inputs samples and output samples. That way someone can write some test code of their own to invoke your code and test your data. – quamrana Dec 18 '19 at 12:16