我有三个班级
class Foo():
def __init__(self, nums):
self.nums = nums
self.num_twos = len([_ for _ in self.nums if _ == 2])
def del_twos(self):
self.nums = [_ for _ in self.nums if _ != 2]
return None
class Bar1():
def __init__(self, nums):
self.nums = nums
def del_twos(self):
self.nums = [_ for _ in self.nums if _ != 2]
return None
@property
def num_twos(self):
return len([_ for _ in self.nums if _ == 2])
class Bar2():
def __init__(self, nums):
self.nums = nums
def del_twos(self):
self.nums = [_ for _ in self.nums if _ != 2]
return None
def num_twos(self):
return len([_ for _ in self.nums if _ == 2])
每个类都由列表nums
启动,每个类都有一个方法del_twos()
,可以从列表2
中删除每个nums
。
此外,每个班级都配有一种方法来计算2
中self.nums
的数量。显然,Bar1
和Bar2
优于Foo
,因为类方法del_twos
可以更改num_twos
的值。
Bar1
和Bar2
之间的唯一区别在于Bar1
' s num_twos
饰有@property
。使用Bar1
优于Bar2
是否有任何优势或劣势?我唯一的区别是Bar1
' s num_twos
可以在没有括号的情况下调用。
答案 0 :(得分:1)
我认为该财产(稍微)优越。
假设你决定Bar2
。
在您使用了一段时间后,您的代码中有很多对num_twos()
的调用,您发现num_twos
被称为远的频率高于{{ 1}},这样你就可以通过使del_twos
像num_twos
中的属性一样实现显着的性能提升。您无需在每次使用时计算其值,只需在必要时更新它:在Foo
内。
如果您这样做,则需要更改所有现有代码才能使用del_twos()
而不是num_twos
,或者必须使num_twos()
成为一个非常简单的包装器查找。
如果您已经使用了属性,则可以使用属性num_twos()
替换属性num_twos
,而无需更改任何现有代码。
这基本上是属性允许您轻松修复num_twos
中的错误的相反情况。在这种情况下,您只需将Foo
替换为动态计算值的属性,而现有代码无需更改。