#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue May 5 21:40:49 2020 @author: root 装饰器语法糖
装饰器的使用方法很固定: 1.先定义一个装饰函数(帽子)(也可以用类、偏函数实现)
2.再定义你的业务函数、或者类(人)
3.最后把这顶帽子带在这个人头上 案例:https://www.jb51.net/article/168276.htm
""" #2日志打印器
# 首先是日志打印器。
# 它要实现的功能是
# 在函数执行前,先打印一行日志告知一下主人,我要执行函数了。
# 在函数执行完,也不能拍拍屁股就走人了,咱可是有礼貌的代码,再打印一行日志告知下主人,我执行完啦。
def logger(func):
def wrapper(*args,**kwargs):
print ('start--------------')
func(*args,**kwargs)
print ('end----------------')
return wrapper @logger
def add(x,y):
print('{} + {} = {}'.format(x, y, x+y)) add(20,90) #3 入门用法:时间计时器
import time
def timer(func):
def wrapper(*args,**kw):
t1=time.time()
func(*args,**kw)
t2=time.time()
cost_time=t2-t1
print ("花费时间:{}秒".format(cost_time))
return wrapper @timer
def want_sleep(sleep_time):
time.sleep(sleep_time)


want_sleep(10)    

# 3进阶用法:带参数的函数装饰器
def say_hello(contry):
def wrapper(func):
def deco(*args,**kwargs):
if contry=='china':
print ("ni hao")
elif contry=='american':
print ('hello')
else:
return
func(*args,**kwargs)
return deco
return wrapper @say_hello('american')
def american():
print ('----------------china') @say_hello('china')
def chinese():
print ('----------------zhongguo') american()
print ('---------------')
chinese() # 高阶用法:不带参数的类装饰器
"""
以上都是基于函数实现的装饰器,在阅读别人代码时,还可以时常发现还有基于类实现的装饰器。
基于类装饰器的实现,必须实现 __call__ 和 __init__两个内置函数。 __init__ :接收被装饰函数
__call__ :实现装饰逻辑
"""
class logger(object):
def __init__(self,func):
self.func=func def __call__(self,*args,**kwargs):
print("[INFO]: the function {func}() is running..."\
.format(func=self.func.__name__))
return self.func(*args,**kwargs) @logger
def say(something):
print ("say {}!".format(something))
say('hello') # 高阶用法:带参数的类装饰器
# 上面不带参数的例子,你发现没有,只能打印INFO级别的日志,正常情况下,我们还需要打印DEBUG WARNING等级别的日志。 这就需要给类装饰器传入参数,给这个函数指定级别了。
# 带参数和不带参数的类装饰器有很大的不同。 # __init__ :不再接收被装饰函数,而是接收传入参数。
# __call__ :接收被装饰函数,实现装饰逻辑 class logger2(object):
def __init__(self,level='INFO'):
self.level=level def __call__(self,func):
def wrapper(*args,**kwargs):
print("[{level}]: the function {func}() is running..."\
.format(level=self.level, func=func.__name__))
func(*args, **kwargs)
return wrapper @logger2(level='warning')
def say(something):
print ("say {}!".format(something))
say('hello') # 内置装饰器:property
# 以上,我们介绍的都是自定义的装饰器。
# 其实Python语言本身也有一些装饰器。比如property这个内建装饰器,我们再熟悉不过了。
# 它通常存在于类中,可以将一个函数定义成一个属性,属性的值就是该函数return的内容。 class Student(object):
def __init__(self, name):
self.name = name
self.name = None @property
def age(self):
return self._age @age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError('输入不合法:年龄必须为数值!')
if not 0 < value < 100:
raise ValueError('输入不合法:年龄范围必须0-100')
self._age=value @age.deleter
def age(self):
del self._age XiaoMing = Student("小明") # 设置属性
XiaoMing.age = 25 print (XiaoMing.name)
print (XiaoMing.age) # example2:
class Student:
def __init__(self,name):
self.name=name @property
def math(self):
return self._math @math.setter
def math(self,value):
if 0<=value<=100:
self._math=value
else:
raise ValueError("Valid value must be in [0, 100]")

实现propetry 装饰器


class TestProperty(object):
    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fset = fset
        self.fget = fget
        self.fdel = fdel
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        print('---in --get')
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError
        return self.fget(obj)

    def __set__(self,obj,value):
        print ('----in --set')
        if self.fset is None:
            raise AttributeError
        self.fset(obj,value)

    def __delete__(self,obj):
        print ('---in ---delete')
        if self.fdel is None:
           raise  AttributeError
        self.fdel(obj)

    def getter(self,fget):
        print ('in getter')
        return type(self)(fget,self.fset,self.fdel,self.__doc__)

    def setter(self,fset):
        print ('in setter')
        return type(self)(fset,self.fget,self.fdel,self.__doc__)
    
    def deleter(self,fdel):
        print ('in fdel')
        return type(self)(fdel,self.fget,self.fset,self.__doc__)

测试一下:

class Student:
def __init__(self, name):
self.name = name # 其实只有这里改变
@TestProperty
def math(self):
return self._math @math.setter
def math(self, value):
if 0 <= value <= 100:
self._math = value
else:
raise ValueError("Valid value must be in [0, 100]")

python 装饰函数2的更多相关文章

  1. Python装饰函数

    from time import ctime, sleep def tsfunc(func): def wrappedFunc(): print('[%s] %s() classed' % (ctim ...

  2. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  3. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  4. Python装饰器、内置函数之金兰契友

    装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...

  5. python之函数对象、函数嵌套、名称空间与作用域、装饰器

    一 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if de ...

  6. python -- 返回函数、匿名函数、装饰器

    返回函数 高阶函数的参数可以是函数,那么其返回值也可以是函数. 闭包 对于高阶函数,内部函数可以引用外部函数的参数和局部变量.当调用外部函数返回内部函数时,相关参数和变量都保存在返回的函数(即内部函数 ...

  7. python装饰器1:函数装饰器详解

    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函 ...

  8. Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器

    目录 一 函数对象 二 函数的嵌套 三 名称空间和作用域 四 闭合函数 五 装饰器 一.函数对象 1.函数是第一类对象 #第一类对象的特性:# 可以被引用 # 可以当做参数传递 # 返回值是函数 # ...

  9. Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器)

    Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器) 1.初始函数 2.函数嵌套及作用域 3.装饰器 4.迭代器和生成器 6.内置函数 7.递归函数 8.匿名函数

随机推荐

  1. 137. 只出现一次的数字 II

    2021-04-30 LeetCode每日一题 链接:https://leetcode-cn.com/problems/single-number-ii/ 方法1:使用map记录每个数出现的次数,再找 ...

  2. ES5中的类

    之前小编对于类和类的基本特征(所谓的封装.继承.多态)理解一直不是很到位,同时在实际项目应用中也用的比较少,今天小编就结合ES5中的基本用法和大家聊聊,希望小伙伴会在这篇文章有属于自己的收获,并能够在 ...

  3. 飞(fly)(数学推导,liu_runda的神题)

    大概看了两三个小时的题解,思考量很大,实现简单........ 20分: 明显看出,每个点的贡献是x*(x-1)/2;即组合数C(x,2),从x个线段中选出2个的方案数,显然每次相交贡献为1,n^2枚 ...

  4. Linux 的ftp服务未启用怎么办

    1.检查是否安装ftp相关的rpm包(如出现下面提示证明是安装过相关rpm包的) [root@rac1 ~]# which vsftpd    /usr/sbin/vsftpd    [root@ra ...

  5. 大数据初级sy

    1.spark 是用以下哪种编程语言实现的? A.C             B  C++       C   JAVA               D.Scala (正确答案) 2.FusionIn ...

  6. CosId 1.0.3 发布,通用、灵活、高性能的分布式 ID 生成器

    CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...

  7. kubelet分析-csi driver注册分析-Node Driver Registrar源码分析

    kubernetes ceph-csi分析目录导航 Node Driver Registrar分析 node-driver-registrar是一个sidecar容器,通过Kubelet的插件注册机制 ...

  8. 图解协程调度模型-GMP模型

    现在无论是客户端.服务端或web开发都会涉及到多线程的概念.那么大家也知道,线程是操作系统能够进行运算调度的最小单位,同一个进程中的多个线程都共享这个进程的全部系统资源. 线程 三个基本概念 内核线程 ...

  9. 15、linux文件、目录的权限及如何改变权限(root用户不受任何权限的限制)

    15.1.linux普通文件的读.写.执行权限说明: r:读,表示具有读取\阅读文件内容的权限: w:可写,表示具有新增,修改文件内容的权限: 如果没有r配合,那么vi编辑文件会提示无法编辑(但可以强 ...

  10. 图的存储与遍历C++实现

    1.图的存储 设点数为n,边数为m 1.1.二维数组 方法:使用一个二维数组 adj 来存边,其中 adj[u][v] 为 1 表示存在 u到 v的边,为 0 表示不存在.如果是带边权的图,可以在 a ...