装饰器

闭包装饰器

装饰器的本质就是一个闭包, 闭包三要素:1 函数嵌套, 2 外部函数返回内部函数的引用, 内部函数使用外部函数的变量
1 使用装饰器简单实现一个登录校验功能

In [1]: user = {"username": "123", "password": 123}def outter(func):...:     def inner(*args, **kwargs):...:         if user.get('token'):...:             return func(*args, **kwargs)...:         else:...:             username = input("user:")...:             password = input("pwd:")...:             if user.get("username") == username:...:                 user['token'] = True...:                 print("login success")...:                 return func(*args, **kwargs)...:             else:...:                 raise ValueError('login faild')...:     return inner...:In [8]: @outter     # func = outer(tests)...: def tests(a, b):...:     print('tests result:',a*b)...:In [9]: tests(2,4)   # outer(tests)(2, 4)
user:123
pwd:123
login success
tests result: 8In [10]: tests(2,4)
tests result: 8In [11]: tests(2,9)
tests result: 18

类中使用的默认装饰器

@classmethod

类中装饰@classmethod魔法方后就属于类方法, 传的第一个参数就是类对象, 可以直接被类对象调用,类方法也可以被实例方法调用,但是类方法不能调用实例方法
使用场景:对于不需要实例化调用的时候调用

 class Method:...:     def __init__(self):...:         pass...:     @classmethod       # 装饰器修饰后变成类方法,可以类直接调用...:     def trf(cls):...:         print(cls)...:     def test(self):       # 实例方法...:         print(self)...:         self.trf()...:...:In [23]: Method.trf()
<class '__main__.Method'>In [24]: Method.test()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-23908d4c4445> in <module>
----> 1 Method.test()TypeError: test() missing 1 required positional argument: 'self'In [25]: s = Method()In [26]: s.trf()
<class '__main__.Method'>In [27]: s.test()
<__main__.Method object at 0x000001ADD8BE3C18>
<class '__main__.Method'>

@staticmethod 方法

staticmethod 方法修饰的实例方法可以不传参数, 跟正常的魔法方法一样

@property 方法

设置property装饰器可以通过实例调用属性一样调用实例,
使用场景:适用于不想被修改的属性可以使用这个装饰

类的魔法方法

new 方法的使用

在类中, 创建实例对象调的第一个方法就是__new__ 魔法方法,new方法给对象分配内存, 所以每个实例初始化时走的一个方法就是new方法
使用场景:常通过这个魔法方法设置单例

In [38]: class bdss:...:     sunclss = None      # 非单例模式下,只要类属性被改变,下一个实例就使用的时被改变的类属性值...:     def __new__(cls, *args, **kwargs):...:         print(cls.sunclss)...:         from random import randint...:         cls.sunclss = randint(1, 40)...:         print('-------',cls.sunclss)...:         return super().__new__(cls, *args, **kwargs)In [39]: a  = bdss()
None
------- 2In [40]: b = bdss()
2
------- 33In [41]: c = bdss()
33
------- 37# 单例实现
In [28]: class bdss:...:     sunclss = None...:     def __new__(cls, *args, **kwargs):...:         if cls.sunclss:...:             return cls.sunclss...:         else:...:             cls.sunclss = super().__new__(cls, *args, **kwargs)...:             return cls.sunclss...:...:In [29]: a = bdss()In [30]: a
Out[30]: <__main__.bdss at 0x1add90c69b0>In [31]: b = bdss()In [32]: b
Out[32]: <__main__.bdss at 0x1add90c69b0>

__call__魔法方法的使用

类中定义了__call__魔法方法可以史类对象像调用函数一样调用,得到结果

In [50]: class A:...:     def __init__(self):...:         pass...:     def __call__(self):...:         print('call method')...:In [51]:In [51]: a = A()In [52]: a()       # 实例属性像调用函数一样调用
call method

使用类装饰器完成单例模式

1 调用装饰器的本质是 外部函数引用内部函数方法,

,所以要用类实现装饰器就也就要实现调用类方法时触发某个类方法, 而__call__方法是调用函数时进行调用的,所以使用类方法做装饰器就必须要call方法

类中常用的三大魔法方法(getattr, setattr, delattr

__getattr__和 getattribute 方法

1 getattribute 在类获取属性时进行调用, 如果类方法中没找到该属性就会触发该getattr方法,父类的getattr方法没有会抛异常,所以如果想不抛异常可以重写getattr方法,使他不抛异常

 class A:...:     def __init__(self):...:         self.a = 'a'...:         self.b = 'b'...:...:     def __getattr__(self, key):...:         print('没获取到该值时有异常调用该')...:         object.__getattribute__(self, key)...:...:In [10]: x = A()In [11]: x.c
没获取到该值时有异常调用该
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-a693afdd9058> in <module>
----> 1 x.c<ipython-input-9-878ca7145054> in __getattr__(self, key)6     def __getattr__(self, key):7         print('没获取到该值时有异常调用该')
----> 8         object.__getattribute__(self, key)910AttributeError: 'A' object has no attribute 'c'

2 setattr魔法方法在设置属性的时候调用, 如果有逻辑要校验可以重写这种方法,使用的场景较多的是如果要将python中的某个键变成实例属性可以用setattr方法

n [9]: class A:...:     def __init__(self):...:         self.a = 'a'...:         self.b = 'b'...:...:     def __setattr__(self, item, value):...:         print('__setattr__')...:         object.__setattr__(self, item, value)...:...:...:...:     def __delattr__(self, item):...:         print('属性删了')...:         object.__delattr__(self, item)...:...:     def __getattr__(self, key):...:         print('没获取到该值时有异常调用该')...:         object.__geta...:         ttribute__(self, key)...:In [10]: xi = A()
__setattr__
__setattr__In [11]: del xi.a
属性删了

python类的魔法方法和装饰器相关推荐

  1. python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)

    在阅读博客中,发现了类装饰器的存在,由于之前就在写类相关的专栏,这次就赶紧补上之前的内容啦.类装饰器这个词是有歧义的,因为类本身可以作为装饰器,一个类也可以被函数装饰器所装饰.今天就简单介绍一下这两种 ...

  2. Python这些魔法方法和装饰器你都知道吗? O(≧▽≦)O Python小知识

    文章目录 魔法方法 __ len __ __ new __ cls与self的区别 Python派生内置不可变类型 __ enter __ 与 __ exit __ __ lt __. __ le _ ...

  3. Python笔记_23_正则相关函数_类中的方法_装饰器_异常

    文章目录 正则相关函数 search 和 match split 切割 sub 替换 finditer 匹配字符串中相应内容,返回迭代器 compile 指定一个统一的匹配规则 正则表达式的修饰符 类 ...

  4. python 类 对象 魔法方法概念+习题

    类 对象 类 对象是c++和java中都有的内容,python定义类的简单语法如下: class 类名: -类变量或者方法 Python 的类定义有点像函数定义,都是以冒号:作为类体的开始,以统一缩进 ...

  5. Python类的魔法方法

    "魔法"方法 1. 打印id() 如果把BMW使用print进行输出的话,会看到如下的信息 即看到的是创建出来的BMW对象在内存中的地址 2. 定义__str__()方法 clas ...

  6. python类的魔法方法基础

    参考:小甲鱼视频 作用:对类进行"刷机"级的修改 魔法方法的标志:①被__xxx__两条下划线包围:如典型的__init__ 1.__init__(self,....) 问:在定义 ...

  7. python深度讲解_《深度剖析CPython解释器》21. Python类机制的深度解析(第五部分): 全方位介绍Python中的魔法方法,一网打尽...

    楔子 下面我们来看一下Python中的魔法方法,我们知道Python将操作符都抽象成了一个魔法方法(magic method),实例对象进行操作时,实际上会调用魔法方法.也正因为如此,numpy才得以 ...

  8. Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法

    Day09新手小白学python 第九节 Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法 目录 Day09新手小白学python 前言 一.面向对象介绍 二 ...

  9. 刻意练习:Python基础 -- Task11. 魔法方法

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

最新文章

  1. hibernate总结-N+1问题
  2. MATLAB 中搭建MatConvNet运行环境(调用GPU运行)以及遇到的错误
  3. Typora+PicGo+Gitee 图床配置
  4. 活动、节假日、促销等营销方式的因果效应评估——特征工程篇(一)
  5. Lucene.Net
  6. ScriptX打印控件的使用
  7. 毕设题目:Matlab疾病识别与分类
  8. Unity自学虚拟摇杆
  9. 计算理论基础 第2版 Harry R. Lewis 第1章
  10. BASE16、BASE32、BASE64编码特征及正则匹配
  11. ABAP 中的搜索帮助
  12. 关闭mongodb数据库 (netstat -lanp | grep “27017“)
  13. 大数据常用的开发工具
  14. Debian 安装手记
  15. MyBatis中设置事务自动提交
  16. AI开发者大会,李彦宏成“宏颜获水”?
  17. 深圳十大绝美看海圣地|深圳海边一日游攻略
  18. 【洛谷1337】[JSOI2004] 吊打XXX(模拟退火经典题)
  19. Linux快速入门之 静态库和动态库 (07)
  20. 软件设计师经典视频教程

热门文章

  1. 怎么做好WMS系统项目的验收
  2. 将正负值分别显示的函数
  3. [肖博数学干货]高考数学二轮复习方法之概率和统计附强化题型解析
  4. 入门,前后端实现简单账号密码登录
  5. 计算机如何恢复桌面,如何恢复计算机桌面图标不见了
  6. 《程序人生》系列-一个月了,我要谢谢,你、你、还有你
  7. JAVA程序把大写转换小写_Java程序将字符串转换为小写和大写。
  8. 继续谈下脑残的NODE_MODULE_VERSION,全世界冷眼看着electron
  9. 一种具有17路可调PWM直流电机的串口遥控机器人
  10. TriSun PDF to X中文版批量pdf转换功能