python知识:装饰器@property到底有啥用途

目录
  • 一、提要
  • 二、关于属性的约定
    • 2.1 类绑定属性
    • 2.2 对象绑定属性
    • 2.3 私有属性
  • 三、应用@property装饰器
    • 3.1 将一个属性转成方法
    • 3.2 私有化某些属性
    • 3.3 关联性修改
    • 3.4 删除属性的deleter方法
  • 四、property()函数原理
  • 总结

一、提要

python的@property是python的一种装饰器,是用来修饰方法的。

python @property 装饰器使一个方法可以像属性一样被使用。

除此之外,还有几个使用场景,本文将叙述这些使用技巧。

二、关于属性的约定

首先看下属性的分类:

2.1 类绑定属性

一般类内属性是指定义成与类同一存储单元的属性,可以类访问。

而当类实例化成对象后,类变量将做为拷贝加入对象,对象所访问的属性是一份拷贝。

这份拷贝修改后易变。

验证代码

class Stranger(object):
    name = 'class name'                #类绑定属性
    def __init__(self, gender=None ):
        self.gender = gender           #对象绑定属性
        self.name = 'new name'         #对象中属性,与类属性的同名拷贝

stan = Stranger('male')
print(1,stan.gender)
stan.gender = 'famel'
print(2,stan.gender)
print(3 stan.name)
print( 4, Stranger.name)

结果:

1 male
2 famel
3 new name
4 class name

2.2 对象绑定属性

凡用self定义的属性,都是对象绑定属性,

  • 内部调用时都需要加上self.
  • 外部调用时用 instance_name.property_name进行访问
class Stranger(object):
    def __init__(self, gender=None ):
        self.gender = gender

stan = Stranger('roma')
print(stan.gender)

stan.gender = 'Paras'
print(stan.gender)

结果:

roma
Paras

注意:事实上实例化后的对象,也可以定义属性,外部也可以调用。 

2.3 私有属性

python的私有属性没有编译限定,知识以单下划线_开头,标记此属性是私有的,但是外部也可以自由访问(私有的程度不够多)。

另一种是双下划线__开头的属性,可以转化成类属性访问

  • 单下划线_开头:只是告诉别人这是私有属性,外部依然可以访问更改
  • 双下划线__开头:外部不可通过instancename.propertyname来访问或者更改,实际将其转化为了_classname__propertyname

三、应用@property装饰器

python的@property是python的一种装饰器,是用来修饰方法的。python @property 装饰器使一个方法可以像属性一样被使用,而不需要在调用的时候带上() 接下来我们会了解什么时候需要使用它,并且在什么场景下需要用到它以及如何合理的使用它。

python类中@property装饰器,相配合的方法有:

  • setter()
  • get()
  • set()

相配合。

3.1 将一个属性转成方法

将一个属性转化为一个方法时,我们最好加上一个@property 装饰器来解决这个问题。

在方法定义上面加一个@property 装饰器,可以在不改变原有调用方式的同时,来将一个属性改为一个方法。

class Goods():
        def __init__(self,unit_price,weight):
            self.unit_price = unit_price
            self.weight = weight

        @property
        def price(self):
            return self.unit_price * self.weight 

lemons = Goods(7,4)
print(lemons.price)

28

上文中,price是方法,现在将方法转化成属性调用。注意这个技巧,要知道原类定义中无price这个属性,这是一个临时产生的结果。类同于excel表格的“计算项”。

3.2 私有化某些属性

对于某些属性,不可直接访问。这里的“直接”就是“无条件”的意思;而条件的访问,就需要装饰器 @property,下例是双装饰器@property和@age.setter配合,对_age进行条件隔离的例子:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self._age = age # 这里的成员属性_age需要与成员方法age()区分开
        self.jobb = job

    # 读取age
    @property # 实现一个age相关的getter方法
    def age(self):
        return self._age

    # 设置age
    @age.setter # 实现一个age相关的setter方法
    def age(self, value):
        if isinstance(value, int):
            self._age = value
        else:
            raise ValueError("'int' type need")

if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    meizi.age = 18  # 使用时注意是.age,不是._age
    print("年龄:{age}".format(age=meizi.age))

注意事项:

  • 属性名与方法名一定要区分开,不然会进入死循环(self._age,def age())
  • 实例化的对象使用属性时,不是调用属性(meizi._age),而是用的方法名(meizi.age)
  • @property其实就是实现了getter功能; @xxx.setter实现的是setter功能;还有一个 @xxx.deleter实现删除功能
  • 定义方法的时候 @property必须在 @xxx.setter之前,且二者修饰的方法名相同(age())
  • 如果只实现了 @property(而没有实现@xxx.setter),那么该属性为 只读属性

3.3 关联性修改

比如,我们输入了first_name、last_name可以得出fullname,下面代码可以实现全名的属性获取。而反过来,对全名进行修改后,如何将连带的first_name、last_name同步进行修改?。

下文中的 @fullname.setter就是解决此类问题的。

class Person():
    def __init__(self, first_name, last_name):
        self.first = first_name
        self.last = last_name

    @property
    def fullname(self):
        return self.first + ' ' + self.last

    @fullname.setter
    def fullname(self, name):
        first_name, last_name = name.split()
        self.first = first_name
        self.last = last_name

    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)

person = Person('zhang', 'san')
print(person.fullname)
print(person.last)
print(person.first)

person.fullname = 'li si'
print(person.fullname)
print(person.last)
print(person.first)

3.4 删除属性的deleter方法

setter 方法类似,当我们需要删除一个属性时,我们会使用deleter 方法。

你可以像定义setter 方法一样来定义一个setter 方法,使用相同的方法名,并在方法上添加@{methodname}.deleter 装饰器 。

class Person():
    def __init__(self, first_name, last_name):
        self.first = first_name
        self.last = last_name

    @property
    def fullname(self):
        return self.first + ' ' + self.last

    @fullname.setter
    def fullname(self, name):
        first_name, last_name = name.split()
        self.first = first_name
        self.last = last_name

    @fullname.deleter
    def fullname(self):
        self.first = None
        self.last = None

    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)

person = Person('zhang', 'san')
print(person.fullname)
print(person.last)
print(person.first)

del person.fullname

print(person.last)
print(person.first)

四、property()函数原理

使用该函数可以将方法直接变成属性,与@property类同。

函数接口:

property(fget=None, fset=None, fdel=None, doc=None)

使用property的代码示例:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self._age = age
        self.jobb = job

    # 设置_age
    def set_age(self, age):
        if isinstance(age, int):
            self._age = age
        else:
            raise ValueError("'int' type need")

    # 读取_age
    def get_age(self):
        return self._age

    # 使得实例化对象可以利用.age方式来访问
    age = property(get_age, set_age)

if __name__ == "__main__":
    # 创建一个“妹子”
    meizi = Stranger()

    meizi.age = 18
    print("年龄:{age}".format(age=meizi.age))

# 输出:
#年龄:18

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • python 中的@property的用法详解

    目录 1.什么是property 2.property属性定义的两种方式 3.用property代替getter和setter方法 1.什么是property 简单地说就是一个类里面的方法一旦被@property装饰,就可以像调用属性一样地去调用这个方法,它能够简化调用者获取数据的流程,而且不用担心将属性暴露出来,有人对其进行赋值操作(避免使用者的不合理操作).需要注意的两点是 调用被装饰方法的时候是不用加括号的 方法定义的时候有且只能有self一个参数 >>> class Goods(

  • 介绍Python的@property装饰器的用法

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑.为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: class Student(object): def get_score(self): return self._score def set_s

  • 详解Python装饰器之@property

    一.property() 函数讲解 了解 @property 装饰器之前,我们首先要了解内置函数的 property(). class property(fget=None, fset=None, fdel=None, doc=None) 描述: 返回 property 属性. 参数说明: fget -- 获取属性值的函数. fset -- 设置属性值的函数. fdel -- 删除属性值函数. doc -- property 属性的文档字符串,如果没有给出 doc,则该 property 将拷贝

  • python知识:装饰器@property到底有啥用途

    目录 一.提要 二.关于属性的约定 2.1 类绑定属性 2.2 对象绑定属性 2.3 私有属性 三.应用@property装饰器 3.1 将一个属性转成方法 3.2 私有化某些属性 3.3 关联性修改 3.4 删除属性的deleter方法 四.property()函数原理 总结 一.提要 python的@property是python的一种装饰器,是用来修饰方法的. python @property 装饰器使一个方法可以像属性一样被使用. 除此之外,还有几个使用场景,本文将叙述这些使用技巧. 二

  • python装饰器property和setter用法

    目录 1.引子:函数也是对象 2.函数内的函数 3.装饰器小栗子 5.property和setter用法 1.引子:函数也是对象 木有括号的函数那就不是在调用. def hi(name="yasoob"): return "hi " + name print(hi()) # output: 'hi yasoob' # 我们甚至可以将一个函数赋值给一个变量,比如 greet = hi # 我们这里没有在使用小括号,因为我们并不是在调用hi函数 # 而是在将它放在gre

  • Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所以我们应该遵循开放封闭的原则. 也就是说:我们必须找到一种解决方案,能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能. 总结:原则如下: 1.不修改源代码 2.不修改调用方式 目的:在遵循1和2原则的基础上扩展新功能. 二.什么是装饰器? 器:指的是工具, 装饰:指的是为被装饰对象添加

  • Python函数装饰器原理与用法详解

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等应用场景.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 严格来说,装饰器只是语法糖,

  • python @propert装饰器使用方法原理解析

    这篇文章主要介绍了python @propert装饰器使用方法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 首先,@propert的作用是把类中的方法『变成』了属性,方便通过实例访问.propert可以有两种用法:可以把一个方法变成只读属性:可以对一些属性进行过滤. 想象这样一个场景,在实例化一个类之后,需要对类的一个属性进行赋值,这时候是没有对属性属性被赋予的值进行判断的,如果属性被赋予了一个不合适的值,那么代码在后面执行的时候就会

  • Python函数装饰器的使用教程

    典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过自由变量绑定后,调用函数并返回结果. 使用clock装饰器: import time from clockdeco import clock @clock def snooze(seconds): time.sleep(seconds) @clock def factorial(n): return 1 if n < 2 else n*factorial(n-1) if _

  • Python 函数装饰器详解

    目录 使用场景 授权(Authorization) 日志(Logging) 带参数的装饰器 在函数中嵌入装饰器 装饰器类 总结 装饰器(Decorators)是 Python 的一个重要部分.简单地说:他们是修改其他函数的功能的函数.他们有助于让我们的代码更简短,也更Pythonic(Python范儿).大多数初学者不知道在哪儿使用它们,所以我将要分享下,哪些区域里装饰器可以让你的代码更简洁.首先,让我们讨论下如何写你自己的装饰器. 这可能是最难掌握的概念之一.我们会每次只讨论一个步骤,这样你能

  • Python的装饰器详情介绍

    目录 1.定义及使用 2.@classmethod 1.定义及使用 例1:装饰器定义: def 装饰器函数(外部函数):            def 内联函数(*args,**kwargs):                ...前置装饰...                外部函数(*args,**kwargs)                ...后置装饰...            return 内联函数  例2:装饰器两种调用方式 第一种:装饰器函数(外部函数)(参数1,参数2....

  • python利用装饰器进行运算的实例分析

    今天想用python的装饰器做一个运算,代码如下 >>> def mu(x): def _mu(*args,**kwargs): return x*x return _mu >>> @mu def test(x,y): print '%s,%s' %(x,y) >>> test(3,5) Traceback (most recent call last): File "<pyshell#111>", line 1, in

  • python函数装饰器用法实例详解

    本文实例讲述了python函数装饰器用法.分享给大家供大家参考.具体如下: 装饰器经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计, 有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. #! coding=utf-8 import time def timeit(func): def wrapper(a): start = time.clock() func

随机推荐