1. 参数的传值和传引用
当参数类型为不可变数据类型时(如数值、字符串、元组等),在函数内部直接修改形参的值不会影响实参。但当参数类型为可变数据类型时(如列表、字典、集合等),在函数内部使用下标或其他方式为其增加、删除或修改元素值时,修改后的结果是可以反映到函数之外的,即实参也会得到相应的修改。前者一般称之为传值(value),后者称之为传引用/传址(address)。

严格意义上来讲,Python并没有提供让程序员自主选择在自定义函数时是采用传值,还是传址的方式来设计参数,而主要是通过Python数据类型的可变和不可变特性来实现。一般来说,使用不可变数据类型变量传递参数就是传值,使用可变数据类型变量传递参数就是传址。
2. 位置参数
在调用函数传递参数时,实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同,这种严格按位置来传递参数称之为位置参数(positional parameters)。

如果在函数参数列表中加入一个斜杠(/)则表示在它之前的形参全都仅限位置形参(positional-only),仅限位置形参没有可供外部使用的名称,在调用仅接受位置形参的函数时,实参只会根据位置映射到形参上。
通过Pillow模块提取exif数据
要从照片中提取exif数据,除了教程中介绍的exifread模块,还可以使用PIL(Python Imaging Library)的ExifTags Module - Pillow。该库提供了广泛的文件格式支持、高效的内部表示和相当强大的图像处理功能。
详细资料可以参考:
参考代码:
import PIL.Image
from PIL.ExifTags import TAGS
from PIL.ExifTags import GPSTAGS
from geopy.point import Point
'''
使用Pillow ExifTags模块
'''
def gps_info(photo_file: str) -> dict:
"""读取照片多exif信息,从中提取GPS数据
Args:
photo_file (str): 照片文件路径
Returns:
dict: 包含经纬度信息的GPS数据字典
"""
gps_data = {}
img = PIL.Image.open(photo_file)
# 找出照片文件中包含的元数据/MetaData
# TAG 字典将16位整数 EXIF 标记枚举映射到描述性字符串名称
# {34853: 'GPSInfo'}
exif_data = {
TAGS[k]: v
for k, v in img._getexif().items() if k in TAGS
}
# GPSTAGS 字典将8位整数 EXIF gps 枚举映射到描述性字符串名称
# {2: 'GPSLatitude'}
if "GPSInfo" in exif_data.keys():
for tag_id in exif_data['GPSInfo'].keys():
# 根据GPS tag id获取tag name
gps_tag = GPSTAGS.get(tag_id, tag_id)
gps_data[gps_tag] = exif_data['GPSInfo'][tag_id]
# 添加float类型的经度和纬度数据项
gps_data['Longitude'] = dms_to_decimal(gps_data['GPSLongitude'], gps_data['GPSLongitudeRef'])
gps_data['Latitude'] = dms_to_decimal(gps_data['GPSLatitude'], gps_data['GPSLatitudeRef'])
return gps_data
def dms_to_decimal(degree: tuple, direction: str) -> float:
# DMS -> Decimal Degree
# {'GPSLongitude': (114.0, 24.0, 17.308959)}
return Point.parse_degrees(degree[0], degree[1], degree[2], direction)
if __name__ == '__main__':
photo_file = 'photo_place/data/IMG_20191221_101137.jpg'
gps_data = gps_info(photo_file)
lng = gps_data['Longitude']
lat = gps_data['Latitude']
print(lng, lat)