Python 什么是「;蟒蛇的;创建一个包含一个元素的列表还是将其保持为空?

Python 什么是「;蟒蛇的;创建一个包含一个元素的列表还是将其保持为空?,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

让我们假设一个have
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