7

在 Python 中,dict 对象有一个“pop”方法,它返回并从 dict 中删除一个键,如果该键不存在,则具有可选的默认值。

对一般对象属性执行此操作的最佳方法是什么?

我在想:

my_obj.__dict__.pop('key_name', default)

应该是一个不错的选择,但我担心直接静音对象的dict可能会产生我不知道的意外副作用。有更好的选择吗?

4

2 回答 2

6

(对于具有__dict__)“弹出”属性的对象与从 中弹出属性相同__dict__,因此您建议的实现是正确的。

编辑:@Erik 正确地指出 using__dict__.pop可以引发 a KeyError,其中适当的异常是 a AttributeError。所以更好的实现会添加 try/catch/reraise-as-AttributeError。

我只想指出,您要做的是“弹出”对象的属性,而不是key

于 2013-10-23T19:43:31.413 回答
3

编辑:一个可能更快且线程安全的替代方案,正确映射KeyErrorAttributeError

_NO_DEFAULT = object()  # so that None could be used as a default value also

def popattr(obj, name, default=_NO_DEFAULT):
    try:
        return obj.__dict__.pop(name)
    except KeyError:
        if default is not _NO_DEFAULT:
            return default
        raise AttributeError("no attribute '%s'" % name)
        # or getattr(obj, name) to generate a real AttributeError

(上一个答案)

像这样的东西应该工作:

def popattr(obj, name):
    ret = getattr(obj, name)
    delattr(obj, name)
    return ret

虽然obj.__dict__.pop(name)也可以工作,但如果KeyError属性不存在而不是AttributeError,我会说后者在语义上对于对象属性访问是正确的;KeyError用于字典,但您并没有真正访问字典;您正在使用的事实__dict__只是属性弹出的一个实现细节,应该被隐藏,这就是popattr它的作用。

于 2013-10-23T19:46:19.483 回答