I am trying to read from one file and write to another file using:
with open('example2') as inpf, open('outputrt','w') as outf:
for l in inpf:
outf.write(l)
But I am getting a syntax error at the line 1 i.e.
"with open('example2') as inpf, open('outputrt','w') as outf:" pointing at "inpf,"
My python version is 2.6. Is there an error in syntax?
That syntax is only supported in 2.7+.
In 2.6 you can do:
import contextlib
with contextlib.nested(open('example2'), open('outputrt','w')) as (inpf, outf):
for l in inpf:
outf.write(l)
Or it might look cleaner to you to do this (this would be my preference):
with open('example2') as inpf:
with open('outputrt','w') as outf:
for l in inpf:
outf.write(l)
In python versons <= 2.6, you can use
inPipe = open("example2", "r")
outPipe = open("outputrt", "w")
for k in inPipe:
outPipe.write(k)
Related
I run a script with the code to open a file and it returns SyntaxError. The script is an open source script that I want to test.
with open(f"/home/mine/myfoldr/myapp.yml", "r") as file:
The line above returns the following error:
File "./startup.py", line 28
with open(f"/home/mine/myfoldr/myapp.yml", 'r') as file:
^
I just don't understand what does it mean with f" here, after open(f"...). Because normally it will be write something like below, without f.
with open("/home/mine/myfoldr/myapp.yml", "r") as file:
I think its not a typo because other line code in the script also..have the same style f, for example:
print(f"Which section do you want to change?"
f"[Application/Controller/Database]")
The f at the start of strings is called f-string, introduced with PEP 489 starting at Python 3.6.
It is used for string formatting, similar to .format(). There are a lot of tutorials on it you can read. The basic example:
x = 22
print('this is {}'.format(x))
print(f'this is {x}')
Here, both lines will output the same resulting string this is 22.
You probably get the error because you are using a version older than Python 3.6, some version where f-strings are not supported.
To test the third-party code you will have to use a newer Python version or modify the code yourself (but this last options may be a lot of work and may introduce some unintentional errors).
I installed the latest TensorFlow (v1.1.0) and I tried to run the tf.contrib.learn Quickstart tutorial, where you suppose to build a classifier for the IRIS data set. However, when I tried:
training_set = tf.contrib.learn.datasets.base.load_csv_with_header(
filename=IRIS_TRAINING,
target_dtype=np.int,
features_dtype=np.float32)
I got a StopIteration error.
When I checked the API, I didn't find anything about the load_csv_with_header(). Have they changed it in the latest version without updating the tutorial? How can I fix this?
EDIT:
I use Python3.6 if this makes any difference.
This is because of the difference between Python 2 and Python 3. Here's my code below that works for Python 3.5:
if not os.path.exists(IRIS_TRAINING):
raw = urllib.request.urlopen(IRIS_TRAINING_URL).read().decode()
with open(IRIS_TRAINING, 'w') as f:
f.write(raw)
if not os.path.exists(IRIS_TEST):
raw = urllib.request.urlopen(IRIS_TEST_URL).read().decode()
with open(IRIS_TEST, 'w') as f:
f.write(raw)
What probably happened is that your code created a file name after IRIS_TRAINING. But the file is empty. Thus StopIteration is raised. If you look into the implementation of load_csv_with_header:
with gfile.Open(filename) as csv_file:
data_file = csv.reader(csv_file)
header = next(data_file)
StopIteration is raised when next does not detect any additional items to read as documented https://docs.python.org/3.5/library/exceptions.html#StopIteration
Note the change in my code compared to the Python 2 version as shown in Tensorflow tutorial:
urllib.request.urlopen instead of urllib.urlopen
decode() is performed after read()
StopIteration should only happen there if the csv file is empty. Did you check that that path (IRIS_TRAINING) resolves to something you have permission to open?
or you can write the csv file as binary instead of adding decode()
if not os.path.exists(IRIS_TRAINING):
raw = urllib.request.urlopen(IRIS_TRAINING_URL).read()
with open(IRIS_TRAINING, 'wb') as f:
f.write(raw)
if the answer above doesn't work, you may specify your path of the iris_training.csv and iris_test.csv file in the urlopen() method.
All I am trying to do is get Python to open and read a file I have created. I realize there are many other ways to do this, but I'm just wondering why this isn't working. I have my file saved in the same location as this as well. Does python recognize rec for records? I just watched a tutorial on this so I'm rather confused
with open('Broncos.txt') as fo:
for rec in fo:
print rec
Syntax Error: print rec: <string>, line 6, pos 17
The syntax error you're receiving is most likely due to the lack of parentheses around your print statement (assuming you're using Python 3). A simple change will allow the program to run:
with open('Broncos.txt') as fo:
for rec in fo:
print(rec)
I think that error is in the last line of your code. You need to include parenthesis around rec in last line of your code:
with open('Broncos.txt') as fo:
for rec in fo:
print (rec)
Python 2 vs. Python 3: print
Very trivial, and the change in the print-syntax is probably the most
widely known change, but still it is worth mentioning: Python 2’s
print statement has been replaced by the print() function, meaning
that we have to wrap the object that we want to print in parantheses.
Python 2 doesn’t have a problem with additional parantheses, but in
contrast, Python 3 would raise a SyntaxError if we called the print
function the Python 2-way without the parentheses.
So you'd need to do this:
with open('Broncos.txt') as fo:
for rec in fo:
print(rec)
abc=123
dabc=123
abc=456
dabc=789
aabd=123
From the above file I need to find lines beginning with abc= (whitespaces doesn't matter)
in ruby I would put this in an array and do
matches = input.grep(/^\s*abc=.*/).map(&:strip)
I'm a totally noob in Python, even said I'm a fresh Python developer is too much.
Maybe there is a better "Python way" of doing this without even grepping ?
The Python version I have available on the platform where I need to solve the problem is 2.6
There is no way of use Ruby at that time
with open("myfile.txt") as myfile:
matches = [line.rstrip() for line in myfile if line.lstrip().startswith("abc=")]
In Python you would typically use a list comprehension whose if clause does what you'd accomplish with Ruby's grep:
import sys, re
matches = [line.strip() for line in sys.stdin
if re.match(r'^\s*abc=.*', line)]
I have a Python codebase, built for Python 3, which uses Python 3 style open() with encoding parameter:
https://github.com/miohtama/vvv/blob/master/vvv/textlineplugin.py#L47
with open(fname, "rt", encoding="utf-8") as f:
Now I'd like to backport this code to Python 2.x, so that I would have a codebase which works with Python 2 and Python 3.
What's the recommended strategy to work around open() differences and lack of encoding parameter?
Could I have a Python 3 open() style file handler which streams bytestrings, so it would act like Python 2 open()?
1. To get an encoding parameter in Python 2:
If you only need to support Python 2.6 and 2.7 you can use io.open instead of open. io is the new io subsystem for Python 3, and it exists in Python 2,6 ans 2.7 as well. Please be aware that in Python 2.6 (as well as 3.0) it's implemented purely in python and very slow, so if you need speed in reading files, it's not a good option.
If you need speed, and you need to support Python 2.6 or earlier, you can use codecs.open instead. It also has an encoding parameter, and is quite similar to io.open except it handles line-endings differently.
2. To get a Python 3 open() style file handler which streams bytestrings:
open(filename, 'rb')
Note the 'b', meaning 'binary'.
I think
from io import open
should do.
Here's one way:
with open("filename.txt", "rb") as f:
contents = f.read().decode("UTF-8")
Here's how to do the same thing when writing:
with open("filename.txt", "wb") as f:
f.write(contents.encode("UTF-8"))
This may do the trick:
import sys
if sys.version_info[0] > 2:
# py3k
pass
else:
# py2
import codecs
import warnings
def open(file, mode='r', buffering=-1, encoding=None,
errors=None, newline=None, closefd=True, opener=None):
if newline is not None:
warnings.warn('newline is not supported in py2')
if not closefd:
warnings.warn('closefd is not supported in py2')
if opener is not None:
warnings.warn('opener is not supported in py2')
return codecs.open(filename=file, mode=mode, encoding=encoding,
errors=errors, buffering=buffering)
Then you can keep you code in the python3 way.
Note that some APIs like newline, closefd, opener do not work
If you are using six, you can try this, by which utilizing the latest Python 3 API and can run in both Python 2/3:
import six
if six.PY2:
# FileNotFoundError is only available since Python 3.3
FileNotFoundError = IOError
from io import open
fname = 'index.rst'
try:
with open(fname, "rt", encoding="utf-8") as f:
pass
# do_something_with_f ...
except FileNotFoundError:
print('Oops.')
And, Python 2 support abandon is just deleting everything related to six.
Not a general answer, but may be useful for the specific case where you are happy with the default python 2 encoding, but want to specify utf-8 for python 3:
if sys.version_info.major > 2:
do_open = lambda filename: open(filename, encoding='utf-8')
else:
do_open = lambda filename: open(filename)
with do_open(filename) as file:
pass