使用property创建可管理的类属性

Published: 2016-09-23

Tags: Python

本文总阅读量

扩展属性

可以使用property对类添加额外的属性,来扩展函数的功能 如下Person类所示,不过想要修改值,需要间接修改first_name, last_name实现

class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    @property
    def full_name(self):
        print('hello, %s %s' % (self.first_name, self.last_name))


p = Person('xiao', 'ming')
p.full_name    #  hello, xiao ming

属性校验

对属性进行校验 当需要对属性在获取或者赋值的同时,希望进行一些额外的操作,可以使用property 新建一个name内置方法,然后用装饰器@property修饰,那么可以使用@name.setter来支持通过赋值来修改变量的值 另外值得注意的是下边注释_name,是可以工作的,因为property在使用同名的变量后,将数据存储在了以下划线开头的_同名变量中 使用self.name = name可以使得初始化的时候也可以进行校验

class Person2(object):
    def __init__(self, name):
        self.name = name
        #self._name = name

    @property
    def name(self):
        print self._name

    @name.setter
    def name(self, value):
        if value != 'gimp':
            self._name = value

p = Person2('xiao ming')
p.name                     # xiao ming
p.name = 'dongdong'
p.name                     # dongdong
p.name = 'gimp'
p.name                     # dongdong

基于原有getattr与setter方法

对于已经定义了获取属性,设置属性的类,可以使用如下方法来对属性进行控制 值得说明的是property后边的参数顺序是不能变的,获取/设置/删除(如果有的话)

class Person3(object):
    def __init__(self, name):
        self._name = name

    def get_name(self):
        print self._name

    def set_name(self, value):
        self._name = value

    name = property(get_name, set_name)


p = Person3('mr.liu')
p.name                 # mr.liu
p.name = 'mr.zhang'
p.name                 # mr.zhang

实用DEMO

这是《Python Cookbook》中的例子,简单清晰,非常不错

import math
class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def area(self):
        return math.pi * self.radius ** 2

    @property
    def perimeter(self):
        return 2 * math.pi * self.radius

不益过多使用

过多的使用property会使得代码变的臃肿,而且有些时候变写大一些的程序,良好的函数命名所表达的意思由于类属性这种方式,使用应合理使用,避免滥用