I am looking to make the below code a bit more efficient / OOP based. As can be seen by the X, Y & Z variables, there is a bit of duplication here. Any suggestions on how to make this code more pythonic?
The code functions as I wish and the end result is to import the dictionary values into a MySQL database with the keys being the column headers.
import fnmatch
import os
import pyexiv2
matches = []
dict1 = {}
# The aim of this script is to recursively search across a directory for all
# JPEG files. Each time a JPEG image is detected, the script used the PYEXIV2
# module to extract all EXIF, IPTC and XMP data from the image. Once extracted
# the key (ie. "camera make" is generated and it's respective value
# (ie. Canon) is then added as the value in a dictionary.
for root, dirnames, filenames in os.walk('C:\Users\Amy\Desktop'):
for filename in fnmatch.filter(filenames, '*.jpg'):
matches.append(os.path.join(root, filename))
for entry in matches:
metadata = pyexiv2.ImageMetadata(entry)
metadata.read()
x = metadata.exif_keys
y = metadata.iptc_keys
z = metadata.xmp_keys
for key in x:
value = metadata[key]
dict1[key] = value.raw_value
for key in y:
value = metadata[key]
dict1[key] = value.raw_value
for key in z:
value = metadata[key]
dict1[key] = value.raw_value
print dict1
1 Answer 1
import fnmatch
import os
import pyexiv2
matches = []
dict1 = {}
dict1
isn't a great name because its hard to guess what it might be for.
# The aim of this script is to recursively search across a directory for all
# JPEG files. Each time a JPEG image is detected, the script used the PYEXIV2
# module to extract all EXIF, IPTC and XMP data from the image. Once extracted
# the key (ie. "camera make" is generated and it's respective value
# (ie. Canon) is then added as the value in a dictionary.
for root, dirnames, filenames in os.walk('C:\Users\Amy\Desktop'):
Your code will be a bit faster if you put stuff into a function rather than at the module level.
for filename in fnmatch.filter(filenames, '*.jpg'):
matches.append(os.path.join(root, filename))
for entry in matches:
ok, you add each file you find to the matches. But then each time you go over all the matches. I doubt you meant to do that. As its stand, you are going to look at the same file over and over again
metadata = pyexiv2.ImageMetadata(entry)
metadata.read()
x = metadata.exif_keys
y = metadata.iptc_keys
z = metadata.xmp_keys
x
y
and z
aren't great variable names. But its seems you aren't really interested in them seperately, just in all the keys. In that case do
keys = metadata.exif_keys + metadata.iptc_keys + metadata.xmp_keys
to combine them all into one list. (I'm guessing as to what exactly these keys are but, I think I it'll work.)
for key in x:
value = metadata[key]
dict1[key] = value.raw_value
I'd combine the two lines
dict1[key] = metadata[key].raw_value
for key in y:
value = metadata[key]
dict1[key] = value.raw_value
for key in z:
value = metadata[key]
dict1[key] = value.raw_value
print dict1
If you put combine x,y,z as above, you'll only need the one loop