Python:谓词方法作为属性?

时间:2015-04-10 18:24:26

标签: python pep8

通过使用@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),但我想知道这是否是标准的东西去做。乍一看,我找不到关于这个主题的任何文件。这种情况有共同标准吗?

1 个答案:

答案 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装饰器的这种处理在一些博客文章(12)中被提及作为主要用例之一 - 允许我们最初编写最简单的代码,并且然后在我们需要功能时切换到@protry-decorated方法。