Python 什么是「;蟒蛇的;创建一个包含一个元素的列表还是将其保持为空?
让我们假设一个havePython 什么是「;蟒蛇的;创建一个包含一个元素的列表还是将其保持为空?,python,Python,让我们假设一个havePerson实例Person个人可能有一个属性id 我想编写一个函数,当属性为None或缺失时,获取一个空列表[],或者当属性id为12时获取列表[12,] def get_id_list(person): try: return [getattr(person, 'id'), ] except AttributeError: return [] 这非常有效,但是否有一种“pythonic”方法可以在不使用try-excep
Person
实例Person
<代码>个人可能有一个属性id
我想编写一个函数,当属性为None
或缺失时,获取一个空列表[]
,或者当属性id
为12时获取列表[12,]
def get_id_list(person):
try:
return [getattr(person, 'id'), ]
except AttributeError:
return []
这非常有效,但是否有一种“pythonic”方法可以在不使用try-except块的情况下,也可以在一行中执行此操作?您可以使用以下方法检查属性:
def get_id_list(person):
if hasattr(person, 'id'):
return [person.id] # better then getattr(person, 'id')
else:
return []
可在一行中写为:
def get_id_list(person):
return [person.id] if hasattr(person, 'id') else []
您可以使用检查属性,如下所示:
def get_id_list(person):
if hasattr(person, 'id'):
return [person.id] # better then getattr(person, 'id')
else:
return []
可在一行中写为:
def get_id_list(person):
return [person.id] if hasattr(person, 'id') else []
允许您在属性不存在时指定默认值,以便在希望避免try/catch块时可以使用该属性
如果命名属性不存在,则返回默认值(如果提供),否则将引发AttributeError
允许您在属性不存在时指定默认值,以便在希望避免try/catch块时可以使用该属性
如果命名属性不存在,则返回默认值(如果提供),否则将引发AttributeError
我会选择
def get_id_list(person):
_id = getattr(person, 'id', None)
return [] if _id is None else [_id]
但是,最好的做法是确保始终定义属性,这样您就不必使用默认的getattr
,也不必使用hasattr
来检查属性是否存在。
def get_id_list(person):
_id = getattr(person, 'id', None)
return [] if _id is None else [_id]
但是,最好的做法是确保始终定义属性,这样您就不必使用默认的
getattr
,也不必使用hasattr
来检查属性是否存在。您的方法是pythonic的,只需做一些调整
首先,不要在try
块内返回。您可以在变量中保留id
值,并在else
子句中正确返回它。原因是您正在执行多个操作,例如获取属性并转换为列表(在其他情况下可能会执行更多操作),而您只是在捕获AttributeError
。当您使用else
时,您可以轻松地处理其他异常,而且从编码风格的角度来看,它更优雅
其次,您不需要使用getattr
,在这种情况下,您可以简单地使用直接属性访问
此外,您可能希望检查对象是否具有属性,然后返回其值,而不是使用try except
,因为请求原谅比获得许可更容易。原则上,试试exepct
更好
def get_id_list(person):
try:
id = person.id
except AttributeError:
return []
else:
return [id]
您的方法是pythonic,只需做一些调整 首先,不要在
try
块内返回。您可以在变量中保留id
值,并在else
子句中正确返回它。原因是您正在执行多个操作,例如获取属性并转换为列表(在其他情况下可能会执行更多操作),而您只是在捕获AttributeError
。当您使用else
时,您可以轻松地处理其他异常,而且从编码风格的角度来看,它更优雅
其次,您不需要使用getattr
,在这种情况下,您可以简单地使用直接属性访问
此外,您可能希望检查对象是否具有属性,然后返回其值,而不是使用try except
,因为请求原谅比获得许可更容易。原则上,试试exepct
更好
def get_id_list(person):
try:
id = person.id
except AttributeError:
return []
else:
return [id]
如果属性不存在,则可以为要返回的函数提供默认值(第三个参数):
def get_id_list(person):
id_ = getattr(person, 'id', None)
return [id_] if id_ is not None else []
(假设
None
不是id
属性的有效值)如果属性不存在,您可以为要返回的函数提供默认值(第三个参数):
def get_id_list(person):
id_ = getattr(person, 'id', None)
return [id_] if id_ is not None else []
(此处假设None
不是id
属性的有效值)根据:
EAFP:
请求原谅比允许更容易。这是一条常见的Python
编码样式假定存在有效的键或属性,并且
如果假设被证明是错误的,则捕获异常。这件衣服又干净又快
风格的特点是有许多尝试和例外
声明。这项技术与许多人常见的LBYL风格形成对比
其他语言,如C
这意味着您的代码遵循“官方的”pythonic方式,检查属性是否存在将减少pythonic
然而,根据person对象不具有
id
属性的频率,性能需求最终可能会覆盖python考虑,因为引发异常比评估简单条件花费更多的时间
考虑以下代码:
import os
from timeit import timeit
def get_id_list_try(person):
try:
return [person.id]
except AttributeError:
return []
def get_id_list_if(person):
if hasattr(person, 'id'):
return [person.id]
else:
return []
class Person(object):
def __init__(self, id):
self.id = id
person_with_id = Person(1664)
person_no_id = object()
print("try with id: {}".format(
timeit("get_id_list_try(person_with_id)", number=1000000,
setup="from __main__ import get_id_list_try, person_with_id")))
print("try no id: {}".format(
timeit("get_id_list_try(person_no_id)", number=1000000,
setup="from __main__ import get_id_list_try, person_no_id")))
print("if with id: {}".format(
timeit("get_id_list_if(person_with_id)", number=1000000,
setup="from __main__ import get_id_list_if, person_with_id")))
print("if no id: {}".format(
timeit("get_id_list_if(person_no_id)", number=1000000,
setup="from __main__ import get_id_list_if, person_no_id")))
它测试try/catch和if/else方法在有id和没有id的情况下的性能。它打印以下内容:
try with id: 0.25232274121
try no id: 2.32747888986
if with id: 0.364873724104
if no id: 0.728008592266
正如您所看到的,当id存在时,try/catch方法要快一点;但当id不存在时,if/else方法比try/catch方法快3倍。根据:
EAFP:
请求原谅比允许更容易。这是一条常见的Python
编码样式假定存在有效的键或属性,并且
如果假设被证明是错误的,则捕获异常。这件衣服又干净又快
风格的特点是有许多尝试和例外
声明。这项技术与许多人常见的LBYL风格形成对比
其他语言,如C
这意味着您的代码遵循“官方的”pythonic方式,检查属性是否存在将减少pythonic
然而,根据person对象不具有
id
属性的频率,性能需求最终可能会覆盖python考虑,因为引发异常比评估简单条件花费更多的时间
考虑以下代码:
import os
from timeit import timeit
def get_id_list_try(person):
try:
return [person.id]
except AttributeError:
return []
def get_id_list_if(person):
if hasattr(person, 'id'):
return [person.id]
else:
return []
class Person(object):
def __init__(self, id):
self.id = id
person_with_id = Person(1664)
person_no_id = object()
print("try with id: {}".format(
timeit("get_id_list_try(person_with_id)", number=1000000,
setup="from __main__ import get_id_list_try, person_with_id")))
print("try no id: {}".format(
timeit("get_id_list_try(person_no_id)", number=1000000,
setup="from __main__ import get_id_list_try, person_no_id")))
print("if with id: {}".format(
timeit("get_id_list_if(person_with_id)", number=1000000,
setup="from __main__ import get_id_list_if, person_with_id")))
print("if no id: {}".format(
timeit("get_id_list_if(person_no_id)", number=1000000,
setup="from __main__ import get_id_list_if, person_no_id")))
它测试了t