(以下是与python3相关的(如果有的话)。)
这是我编写的代码(简化):
class MyClass: def __init__(self): self.__some_var = [] @property def some_var(self): return self.__some__var @some_var.setter def some_var(self, new_value): if hasattr(new_value, '__iter__'): self.__some_var = new_value else: self.__some_var.append(new_value)
我想在设置时替换它们是否是几个“值”(即,如果new_value是可迭代的,在我的情况下是非可迭代的对象),并且如果它们只是一个“值”则附加。 我很关心hasattr的性能,所以我想知道我是不是应该使用这个setter:
@some_var.setter def some_var(self, *args): if len(args) > 1: self.__some_var = args else: self.__some_var.append(args)
感谢您的关注!
答案 0 :(得分:4)
重要的是hasattr
的“性能成本”。它足够快,你很难测量它。
请不要使用__
(双下划线)作为您自己的属性。这让我们其他人感到困惑。
通常最好使用collections
抽象基类成员资格来处理此类事情。
if isinstance( arg, collections.Sequence ):
self._some_var = list(arg)
else:
self._some_var.append( arg )
这为你提供了一些可能更好的工作,因为它更清晰地表达了语义。
答案 1 :(得分:2)
替代方案可能是鸭子打字:
这里我假设您要从迭代中评估(=制作一个列表),因为它可能是一个需要立即扩展以保存的迭代器。
@some_var.setter
def some_var(self, new_value):
try:
self.__some_var = list(new_value)
except TypeError:
self.__some_var.append(new_value)
如果list()
不可迭代,我们希望ValueError
提升new_value
。作为对你对S.Lott答案的评论的回应,我认为使用hasattr并不是真正的鸭子打字风格。
答案 2 :(得分:0)
在效率方面: