如何使 python 代码更简洁、优化和高效?

How can I make python code cleaner, optimized, and efficient?

我在 python 3 中编写了一个程序,它从图像中提取元数据并使用此信息执行多项操作。其中一个功能是它会从元数据中提取 GPS 坐标,并使用 google 地图的静态 API 绘制该位置的地图。

一切正常,但我写了这个非常混乱的代码来从找到的数据中提取坐标。我怎样才能清理这段代码使其更有效率?我也很感激编写更好代码的任何提示。

提前致谢。

这是输入数据的示例:(为了保存而缩短 space)

    EXIF BrightnessValue: 10
    EXIF ColorSpace: sRGB
    EXIF ComponentsConfiguration: YCbCr
    EXIF Contrast: Normal
    EXIF CustomRendered: Normal
    EXIF DateTimeDigitized: 2006:10:11 09:37:52
    EXIF DateTimeOriginal: 2006:10:11 09:37:52
    EXIF DigitalZoomRatio: 0
    EXIF ExifImageLength: 768
    EXIF ExifImageWidth: 1024
    EXIF ExifVersion: 0221
    EXIF ExposureBiasValue: 0
    EXIF ExposureMode: Auto Exposure
    EXIF ExposureProgram: Aperture Priority
    EXIF ExposureTime: 1/800
    EXIF FNumber: 71/10
    EXIF Flash: Flash did not fire, compulsory flash mode
    GPS GPSAltitude: 0
    GPS GPSAltitudeRef: 0
    GPS GPSLatitude: [33, 51, 2191/100]
    GPS GPSLatitudeRef: S
    GPS GPSLongitude: [151, 13, 1173/100]
    GPS GPSLongitudeRef: E
    GPS GPSVersionID: [0, 0, 2, 2]
    Image Artist:  
    Image Copyright:  
    Image DateTime: 2006:10:11 09:37:52
    Image ExifOffset: 346
    Image GPSInfo: 946
    Image ImageDescription: KONICA MINOLTA DIGITAL CAMERA
    Image Make: Konica Minolta Camera, Inc.
    Image Model: DiMAGE A2
    Image Orientation: Horizontal (normal)

这是我的代码的作用(输出):

    ['33', '51', '2191/100', 'S', '151', '13', '1173/100', 'E']

它提取 GPSLatitude、GPSLatitudeRef、GPSLongitude 和 GPSLongitudeRef,并按照上面显示的顺序将它们分配给单个列表。 (顺序很重要,因为其他函数依赖于这个列表的顺序)

代码段:

def coordinates_extractor():
    out = []

    lat1 = []
    lon1 = []

    lat2 = []
    lon2 = []

    lat3 = []
    lon3 = []

    lat4 = []
    lon4 = []

    ALL = []

    for tag in tags.keys():
        if tag not in ("JPEGThumbnail", "TIFFThumbnail", "EXIF MakerNote"):
            out += [("%s: %s" % (tag, tags[tag]))]
        out = sorted(out)

    for i in out:
        if "GPSLatitudeRef:" in i:
            lat1 += [i]
        if "GPSLatitude:" in i:
            lat1 += [i]

    for i in out:
        if "GPSLongitudeRef:" in i:
            lon1 += [i]
        if "GPSLongitude:" in i:
            lon1 += [i]

    for i in lat1:
        lat2 += i.split()

    del lat2[0]
    del lat2[0]
    del lat2[3]
    del lat2[3]

    for i in lat2:
        if "[" in i:
            lat3 += [i.replace("[", "")]
            continue
        if "]" not in i:
            lat3 += [i]
        if "]" in i:
            lat3 += [i.replace("]", "")]

    for i in lat3:
        if "," in i:
            lat4 += [i.replace(",", "")]
        if "," not in i:
            lat4 += [i]

    for i in lon1:
        lon2 += i.split()

    del lon2[0]
    del lon2[0]
    del lon2[3]
    del lon2[3]

    for i in lon2:
        if "[" in i:
            lon3 += [i.replace("[", "")]
            continue
        if "]" not in i:
            lon3 += [i]
        if "]" in i:
            lon3 += [i.replace("]", "")]

    for i in lon3:
        if "," in i:
            lon4 += [i.replace(",", "")]
        if "," not in i:
            lon4 += [i]

    LATANDLONG = lat4 + lon4

    return LATANDLONG

示例标签摘自:http://ptforum.photoolsweb.com/ubbthreads.php?ubb=download&Number=1024&filename=1024-2006_1011_093752.jpg

你可以尝试这样的事情。我包含了一个模拟的 dict 对象,以便在没有图像的情况下轻松地 运行。您只需要删除它并将其替换为 exifread 库提供的真实 tags 对象,我相信您正在使用它。

# mock dictionary because I dont have your image
tags = {}
tags['GPS GPSLatitude'] =  [33, 51, 2191/100]
tags['GPS GPSLatitudeRef'] = 'S'
tags['GPS GPSLongitude'] = [151, 13, 1173/100]
tags['GPS GPSLongitudeRef'] = 'E'

out = []
wantedtags = ('GPS GPSLatitude', 'GPS GPSLatitudeRef', 'GPS GPSLongitude', 'GPS GPSLongitudeRef')

for tag in wantedtags:
    try:
        val = tags[tag]
        if isinstance(val, list):
            out.extend(map(str, val))
        else:
            out.append(val)
    except KeyError:
        print('Key %s does not exists' % tag)

print(out)

但请注意,输出与您的预期输出完全不同。原因是文字 2191/1001173/100 在 运行 时被评估为除法语句,并且在列表中被视为 21 & 11 for python 2 和 21.91 & 11.73 for python 3. 在 python 2 中使用 from __future__ import division 以获得更精确的除法结果。

exifread 的行为是否不同?即它是否以其他形式存储此值以保持分数值而不仅仅是普通的旧整数?

我 运行 你自己的代码对照我自己模拟的字典,输出与我的版本完全一样。