通过使用@property
装饰器,Python完全消除了对对象属性的getter和setter的需要(有些人可能会说'属性')。这使得代码更加简单,同时在需要变得更复杂时保持可扩展性。
我想知道Pythonic采用以下方法的方法是什么。说我有以下课程:
class A(object):
def is_winner(self):
return True # typically a more arcane method to determine the answer
此类方法通常不带参数,也没有副作用。有人可能称之为这些谓词。根据他们的名字,他们通常非常类似于人们可能存储的财产。
我倾向于在上面添加@property
装饰器,以便能够将其称为对象属性(即foo.is_winner
),但我想知道这是否是标准的东西去做。乍一看,我找不到关于这个主题的任何文件。这种情况有共同标准吗?
答案 0 :(得分:2)
似乎普遍的共识是属性通常被视为即时和下一个自由使用,因此如果计算被装饰为@property是昂贵的,那么最好是重复缓存结果使用(@Martijn Pieters)或将其保留为方法,因为通常期望方法比属性查找花费更多时间。 PEP 8具体说明:
注2:尝试保持功能行为副作用不受影响,尽管缓存等副作用通常都很好。
注3:避免使用属性进行计算成本高昂的操作;属性表示法使调用者相信访问(相对)便宜。
@property装饰器的一个特定用例是向类中添加一些行为,而不要求类的用户从foo.bar
引用更改为foo.bar()
调用 - 例如,如果您需要要计算引用属性的次数,可以将属性转换为@property,其中装饰方法在返回请求的数据之前处理某些状态。
以下是原始类的示例:
class Cat(object):
def __init__(self, name):
self.name = name
# In user code
baxter = Cat('Baxter')
print(baxter.name) # => Baxter
使用@property装饰器,我们现在可以在不影响用户代码的情况下添加一些引擎盖下的机器:
class Cat(object):
def __init__(self, name):
self._name = name
self._name_access_count = 0
@property
def name(self):
self._name_access_count += 1
return self._name
# User code remains unchanged
baxter = Cat('Baxter')
print(baxter.name) # => Baxter
# Also have information available about the number of times baxter's name was accessed
print(baxter._name_access_count) # => 1
baxter.name # => 'Baxter'
print(baxter._name_access_count) # => 2
@property装饰器的这种处理在一些博客文章(1,2)中被提及作为主要用例之一 - 允许我们最初编写最简单的代码,并且然后在我们需要功能时切换到@protry-decorated方法。