Python AttributeError: 'str' object has no attribute 'namelist' - python

I am trying to create a very simple log parser script in python. Everything is going as planned except the script on the target machine is returning this error (the script works on a unix machine though quite fine):
for name in root.namelist():
Attribute Error: 'str' object has no attribute 'namelist'
Python versions appear to be the same (2.7.3 on both machines). Any ideas?
Script itself:
import zipfile
import os
import re
string1 = "searchstring" # raw_input("usrinput: ")
try:
root = zipfile.ZipFile("/home/testuser/docs/testzip.zip", "r")
except:
root = "testfolder/"
for name in root.namelist():
if name.find(".") > 0:
f = root.open(name)
searchlines = f.readlines()
for i, line in enumerate(searchlines):
regex1 = "(.*)" + re.escape(string1) + "(.*)"
if re.match (regex1, line):
for l in searchlines[i-4:i+4]: print l,
print

This is because root = "testfolder/" it doesn't have any namelist as its attribute.
Type of root is string
Which in turn looking at your code means, root = zipfile.ZipFile("/home/testuser/docs/testzip.zip", "r") generated an exception
in exception block try to use except Exception, ex: and then print ex.message to understand the type of exception being generated

This is because, namelist() is only available for a zipfile, not for a string.
This happens when the zip file cannot be opened. Check the path where the zip file is located.
Try this and see the output:
try:
root = zipfile.ZipFile("/home/testuser/docs/testzip.zip", "r")
except Exception, msg:
print msg
root = "testfolder/"
When I tried with a valid zip file, the program worked fine.

Related

.read() returns "unicode object has no attribute read" in python with askopenfilename()

I'm trying to make an import function for scrolledText in Python's Tkinter, but when reading the file, an AttributeError is raised. Code:
def open_command():
openfile = tkFileDialog.askopenfilename()
if openfile != None:
contents = openfile.read()
textPad.delete('1.0', END)
textPad.insert('1.0', contents)
openfile.close()
Error:
contents = openfile.read()
AttributeError: 'unicode' object has no attribute 'read'
I want to clarify that 'textPad' refers to a 'ScrolledText' object.
Does anyone know why this is happening? at first I thought the error may be coming from encoding, so I encoded in UTF-8 but it still returned the same error. Thanks in advance!
tkFileDialog.askopenfilename() returns the file name not a file object. You'll want to do something like:
def open_command():
filename = tkFileDialog.askopenfilename()
if filename is not None:
with open(filename) as f:
contents = f.read()
textPad.delete('1.0', END)
textPad.insert('1.0', contents)
[If you're using Python 2.7 consider using Python 3 or change the above to open(filename, 'r')]

os.scandir gives [WinError 3] The system cannot find the path specified

I have a (large) set of XML files that I want to search for a set of strings all being present within - I am trying to use the following Python code to do this:
import collections
thestrings = []
with open('Strings.txt') as f:
for line in f:
text = line.strip()
thestrings.append(text)
print('Searching for:')
print(thestrings)
print('Results:')
try:
from os import scandir
except ImportError:
from scandir import scandir
def scantree(path):
"""Recursively yield DirEntry objects for given directory."""
for entry in scandir(path):
if entry.is_dir(follow_symlinks=False) and (not entry.name.startswith('.')):
yield from scantree(entry.path)
else:
yield entry
if __name__ == '__main__':
for entry in scantree('//path/to/folder'):
if ('.xml' in entry.name) and ('.zip' not in entry.name):
with open(entry.path) as f:
data = f.readline()
if (thestrings[0] in data):
print('')
print('****** Schema found in: ', entry.name)
print('')
data = f.read()
if (thestrings[1] in data) and (thestrings[2] in data) and (thestrings[3] in data):
print('Hit at:', entry.path)
print("Done!")
Where Strings.txt is a file with the strings I am interested to find, and the first line is the schema URI.
This seems to run OK at first, but after some seconds gives me a:
FileNotFoundError: [WinError 3] The system cannot find the path specified: //some/path
Which is confusing me, since the path is being built during runtime?
Note, if I instrument the code as follows:
with open(entry.path) as f:
data = f.readline()
if (thestrings[0] in data):
To become:
with open(entry.path) as f:
print(entry.name)
data = f.readline()
if (thestrings[0] in data):
Then I see a number of potential files being found before the error occurs.
I realised that my script is finding some very long UNC path names, too long for Windows it seems, so I am now also checking the path length before attempting to open the file, as follows:
if name.endswith('.xml'):
fullpath = os.path.join(root, name)
if (len(fullpath) > 255): ##Too long for Windows!
print('File-extension-based candidate: ', fullpath)
else:
if os.path.isfile(fullpath):
with open(fullpath) as f:
data = f.readline()
if (thestrings[0] in data):
print('Schema-based candidate: ', fullpath)
Note, I also decided to check if the file really is a file, and I altered my code to use os.walk, as suggested above. Along with simplifying the check for a .xml file-extension by using .endswith()
Everything now seems to work OK...

Using the with statement in Python 2.5: SyntaxError?

I have the following python code, its working fine with python 2.7, but I want to run it on python 2.5.
I am new to Python, I tried to change the script multiple times, but i always I got syntax error. The code below throws a SyntaxError: Invalid syntax:
#!/usr/bin/env python
import sys
import re
file = sys.argv[1]
exp = sys.argv[2]
print file
print exp
with open (file, "r") as myfile:
data=myfile.read()
p = re.compile(exp)
matches = p.findall(data)
for match in matches:
print " ".join("{0:02x}".format(ord(c)) for c in match)
Python 2.5 doesn't support the with statement yet.
To use it in Python 2.5, you'll have to import it from __future__:
## This shall be at the very top of your script ##
from __future__ import with_statement
Or, as in the previous versions, you can do the procedure manually:
myfile = open(file)
try:
data = myfile.read()
#some other things
finally:
myfile.close()
Hope it helps!
Python 2.5 does not have the with code block support.
Do this instead:
myfile = open(file, "r")
try:
data = myfile.read()
p = re.compile(exp)
matches = p.findall(data)
for match in matches:
print " ".join("{0:02x}".format(ord(c)) for c in match)
finally:
myfile.close()
note: you should not use file as the name of your file, it is an internal Python name, and it shadows the built in.

Python shell freezes on reading (fasta) file

I am going to start of by showing the code I have thus far:
def err(em):
print(em)
exit
def rF(f):
s = ""
try:
fh = open(f, 'r')
except IOError:
e = "Could not open the file: " + f
err(e)
try:
with fh as ff:
next(ff)
for l in ff:
if ">" in l:
next(ff)
else:
s += l.replace('\n','').replace('\t','').replace('\r','')
except:
e = "Unknown Exception"
err(e)
fh.close()
return s
For some reason the python shell (I am using 3.2.2) freezes up whenever I tried to read a file by typing:
rF("mycobacterium_bovis.fasta")
The conditionals in the rF function are to prevent reading each line that starts with a ">" token. These lines aren't DNA/RNA code (which is what I am trying to read from these files) and should be ignored.
I hope anyone can help me out with this, I don't see my error.
As per the usual, MANY thanks in advance!
EDIT:
*The problem persists!*
This is the code I now use, I removed the error handling which was a fancy addition anyway, still the shell freezes whenever attempting to read a file. This is my code now:
def rF(f):
s = ""
try:
fh = open(f, 'r')
except IOError:
print("Err")
try:
with fh as ff:
next(ff)
for l in ff:
if ">" in l:
next(ff)
else:
s += l.replace('\n','').replace('\t','').replace('\r','')
except:
print("Err")
fh.close()
return s
You didn't ever define e.
So you'll get a NameError that is being hidden by the naked except:.
This is why it is good and healthy to specify the exception, e.g.:
try:
print(e)
except NameError as e:
print(e)
In cases like yours, though, when you don't necessarily know what the exception will be you should at least use this method of displaying information about the error:
import sys
try:
print(e)
except: # catch *all* exceptions
e = sys.exc_info()[1]
print(e)
Which, using the original code you posted, would have printed the following:
name 'e' is not defined
Edit based on updated information:
Concatenating a string like that is going to be quite slow if you have a large file.
Consider instead writing the filtered information to another file, e.g.:
def rF(f):
with open(f,'r') as fin, open('outfile','w') as fou:
next(fin)
for l in fin:
if ">" in l:
next(fin)
else:
fou.write(l.replace('\n','').replace('\t','').replace('\r',''))
I have tested that the above code works on a FASTA file based on the format specification listed here: http://en.wikipedia.org/wiki/FASTA_format using Python 3.2.2 [GCC 4.6.1] on linux2.
A couple of recommendations:
Start small. Get a simple piece working then add a step.
Add print() statements at trouble spots.
Also, consider including more information about the contents of the file you're attempting to parse. That may make it easier for us to help.

Stop an operation without stopping the module in python

Well, I have made a module that allows you to copy a file to a directory easier. Now, I also have some "try's" and "except's" in there to make sure it doesn't fail in the big messy way and doesn't close the terminal, but I also want it to display different error messages when a wrong string or variable is put in, and end the module, but not the...if I may say, Terminal running it, so I did this:
def copy():
import shutil
import os
try:
cpy = input("CMD>>> Name of file(with extension): ")
open(cpy, "r")
except:
print("ERROR>>> 02x00 No such file")
try:
dri = input("CMD>>> Name of Directory: ")
os.chdir(dri)
os.chdir("..")
except:
print("ERROR>>> 03x00 No such directory")
try:
shutil.copy(cpy, dri)
except:
print("ERROR>>> 04x00 Command Failure")
Problem is that it doesn't end the module if there is no file or directory, only at the finish.
You may be thinking that when an exception is raised, Python just stops what it's doing, but that's not quite true. The except: block actually catches the exception raised, and is supposed to handle it. After an except: block finishes, Python will continue on executing the rest of the code in the file.
In your case, I'd put a return after each print(...). That way, after Python prints out an error message, it will also return from the copy() function rather than continuing to ask for more input.
If you did want to make the module exit on error...
Here's how you'd do it.
def copy():
import shutil
import os
import sys
try:
cpy = input("CMD>>> Name of file(with extension): ")
open(cpy, "r")
except:
sys.exit("ERROR>>> 02x00 No such file")
try:
dri = input("CMD>>> Name of Directory: ")
os.chdir(dri)
os.chdir("..")
except:
sys.exit("ERROR>>> 03x00 No such directory")
try:
shutil.copy(cpy, dri)
except:
sys.exit("ERROR>>> 04x00 Command Failure")
sys.exit(0) (for success) and sys.exit(1) (for failure) are usually used but, since you want to output the error, the above example will output the error string to stderr.
Here's a link for more info on sys.exit().

Categories