title: Python write valid json with newlines to file
body: <p>Valid json expects escaped newline characters to be encoded as '\\n', with two backslashes. I have data that contains newline characters that I want to save to a file. Here's a simplified version:</p>
  
  <pre><code>data = {'mystring': 'Line 1\nLine 2'}
  </code></pre>
  
  <p>I can encode it with json.dumps():</p>
  
  <pre><code>import json
  json_data = json.dumps(data)
  json_data
  # -&gt; '{"mystring": "Line 1\\nLine 2"}'
  </code></pre>
  
  <p>When I print it, the newline displays as '\n', not '\\n' (which I find odd but I can live with):</p>
  
  <pre><code>print(json_data)
  # -&gt; {"mystring": "Line 1\nLine 2"}
  </code></pre>
  
  <p>However (here's the problem) when I output it to a file, the content of the file no longer contains valid json:</p>
  
  <pre><code>f = open('mydata.json', 'w')
  f.write(json_data)
  f.close()
  </code></pre>
  
  <p>If I open the file and read it, it contains this:</p>
  
  <pre><code>{"mystring": "Line 1\nLine 2"}
  </code></pre>
  
  <p>but I was hoping for this:</p>
  
  <pre><code>{"mystring": "Line 1\\nLine 2"}
  </code></pre>
  
  <p>Oddly (I think), if I read the file using python's open(), the json data is considered valid:</p>
  
  <pre><code>f = open('mydata.json', 'r')
  json_data = f.read()
  f.close()
  json_data
  # -&gt; '{"mystring": "Line 1\\nLine 2"}'
  </code></pre>
  
  <p>... and it decodes OK:</p>
  
  <pre><code>json.loads(json_data)
  # -&gt; {u'mystring': u'Line 1\nLine 2'}
  </code></pre>
  
  <p>My question is <em>why is the data in the file not valid json</em>? If I need another - non Python - application to read it it would probably be incorrect. If I copy and paste the file contents and use json.loads() on it it fails:</p>
  
  <pre><code>import json
  json.loads('{"mystring": "Line 1\nLine 2"}')
  # -&gt; ValueError: Invalid control character at: line 1 column 21 (char 20)
  </code></pre>
  
  <p>Can anybody explain if this is the expected behaviour or am I doing something wrong?</p>