在Python中,dict對象有一個「pop」方法,該方法返回並從字典中移除一個鍵,如果該鍵不存在則使用可選的默認值。如何在python中實現屬性彈出
對一般對象屬性做這件事的最好方法是什麼?
我在想:
my_obj.__dict__.pop('key_name', default)
應該是一個不錯的選擇,但我擔心,直接屏蔽對象的字典可能有意想不到的副作用,我是不知道的。有更好的選擇嗎?
在Python中,dict對象有一個「pop」方法,該方法返回並從字典中移除一個鍵,如果該鍵不存在則使用可選的默認值。如何在python中實現屬性彈出
對一般對象屬性做這件事的最好方法是什麼?
我在想:
my_obj.__dict__.pop('key_name', default)
應該是一個不錯的選擇,但我擔心,直接屏蔽對象的字典可能有意想不到的副作用,我是不知道的。有更好的選擇嗎?
(對於具有__dict__
的對象)「彈出」屬性與將它從__dict__
中彈出相同,因此您的建議實現是正確的。
編輯:@Erik正確指出,使用__dict__.pop
可以提高KeyError
,其中相應的例外是AttributeError
。所以更好的實現會添加try/catch/reraise-as-AttributeError。
我只想指出的是,你正在試圖做的是「啪」一個對象的屬性,不是關鍵。
編輯:一個可能更快,螺紋與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
所做的。
你爲什麼要這樣做?在Python中以這種方式處理對象屬性通常不是一個好主意。 – user2357112
你到底在問什麼?我的意思是,你會使用'my_obj.pop('key_name',default)',然後你會實現一些對你的對象有意義的事情,如果它代表離子風暴或冰激凌卡車... –
僅僅因爲對象的屬性是用字典實現的,並不意味着對象本身支持「流行」操作是有意義的。面向對象設計的一部分是每個類的實例共享由類定義的某些屬性。從一個對象中去除這樣的屬性,而不是另一個對象打破了這種設計。 – chepner