在 Python 中,dict 对象有一个“pop”方法,它返回并从 dict 中删除一个键,如果该键不存在,则具有可选的默认值。
对一般对象属性执行此操作的最佳方法是什么?
我在想:
my_obj.__dict__.pop('key_name', default)
应该是一个不错的选择,但我担心直接静音对象的dict可能会产生我不知道的意外副作用。有更好的选择吗?
在 Python 中,dict 对象有一个“pop”方法,它返回并从 dict 中删除一个键,如果该键不存在,则具有可选的默认值。
对一般对象属性执行此操作的最佳方法是什么?
我在想:
my_obj.__dict__.pop('key_name', default)
应该是一个不错的选择,但我担心直接静音对象的dict可能会产生我不知道的意外副作用。有更好的选择吗?
(对于具有__dict__
)“弹出”属性的对象与从 中弹出属性相同__dict__
,因此您建议的实现是正确的。
编辑:@Erik 正确地指出 using__dict__.pop
可以引发 a KeyError
,其中适当的异常是 a AttributeError
。所以更好的实现会添加 try/catch/reraise-as-AttributeError。
我只想指出,您要做的是“弹出”对象的属性,而不是key。
编辑:一个可能更快且线程安全的替代方案,正确映射KeyError
到AttributeError
:
_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
它的作用。