快速重构Python代码:利用@property装饰器

从前,Python程序员Alice要打算创建一个代表金钱的类。她的第一个实现形式大概是下面这样:

#以美元为基础货币的Money类的首个版本

class Money:

    def __init__(self, dollars, cents):

        self.dollars = dollars

        self.cents = cents

        #还有其他一些方法,我们暂时不必理会


        几个月或是几年之后。Alice想要重构Money类的内部实现,不再记录美元和美分,而是仅仅记录美分,因为这样做可以让某些操作简单很多。下面是她很可能会作的修改:

#Money类的第二个版本

class Money:

    def __init__(self, dollars, cents):

        self.total_cents = dollars * 100 + cents


        幸运的是,Alice知道一种更好的解决办法,可以避免这个令人头疼的局面出现:使用Python内建的property装饰器。@property一般应用在Python方法上,可以有效地将属性访问(attribute access)变成方法调用(method call)。举个例子,暂时将Money类抛至一边,假设有一个代表人类的Person类(class):

class Person:

    def __init__(self, first, last):        self.first = first

        self.last = last

    @property

    def full_name(self):

        return '{} {}'.format(self.first, self.last)

        请注意full_name方法。除了在def语句上方装饰了@property之外,该方法的声明没有什么不同的地方。但是,这却改变了Person对象的运作方式

>>> buddy = Person('Jonathan', 'Doe')

>>> buddy.full_name

'Jonathan Doe'

        我们发现,尽管full_name被定义为一个方法,但却可以通过变量属性的方式访问。在最后一行代码中没有()操作符;我并没有调用full_name方法。我们所做的,可以说是创建了某种动态属性


回到本文中的Money类,Alice对它作了如下修改:

# Money类的最终版本

class Money:

    def __init__(self, dollars, cents):        

            self.total_cents = dollars * 100 + cents

    # Getter and setter for dollars...

    @property

    def dollars(self):

        return self.total_cents // 100;

    @dollars.setter

    def dollars(self, new_dollars):        

            self.total_cents = 100 * new_dollars + self.cents

      # And the getter and setter for cents.

    @property

    def cents(self):

        return self.total_cents % 100;

    @cents.setter

    def cents(self, new_cents):        

            self.total_cents = 100 * self.dollars + new_cents

你可能感兴趣的:(快速重构Python代码:利用@property装饰器)