python类的魔法方法和装饰器
装饰器
闭包装饰器
装饰器的本质就是一个闭包, 闭包三要素: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类的魔法方法和装饰器相关推荐
- python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)
在阅读博客中,发现了类装饰器的存在,由于之前就在写类相关的专栏,这次就赶紧补上之前的内容啦.类装饰器这个词是有歧义的,因为类本身可以作为装饰器,一个类也可以被函数装饰器所装饰.今天就简单介绍一下这两种 ...
- Python这些魔法方法和装饰器你都知道吗? O(≧▽≦)O Python小知识
文章目录 魔法方法 __ len __ __ new __ cls与self的区别 Python派生内置不可变类型 __ enter __ 与 __ exit __ __ lt __. __ le _ ...
- Python笔记_23_正则相关函数_类中的方法_装饰器_异常
文章目录 正则相关函数 search 和 match split 切割 sub 替换 finditer 匹配字符串中相应内容,返回迭代器 compile 指定一个统一的匹配规则 正则表达式的修饰符 类 ...
- python 类 对象 魔法方法概念+习题
类 对象 类 对象是c++和java中都有的内容,python定义类的简单语法如下: class 类名: -类变量或者方法 Python 的类定义有点像函数定义,都是以冒号:作为类体的开始,以统一缩进 ...
- Python类的魔法方法
"魔法"方法 1. 打印id() 如果把BMW使用print进行输出的话,会看到如下的信息 即看到的是创建出来的BMW对象在内存中的地址 2. 定义__str__()方法 clas ...
- python类的魔法方法基础
参考:小甲鱼视频 作用:对类进行"刷机"级的修改 魔法方法的标志:①被__xxx__两条下划线包围:如典型的__init__ 1.__init__(self,....) 问:在定义 ...
- python深度讲解_《深度剖析CPython解释器》21. Python类机制的深度解析(第五部分): 全方位介绍Python中的魔法方法,一网打尽...
楔子 下面我们来看一下Python中的魔法方法,我们知道Python将操作符都抽象成了一个魔法方法(magic method),实例对象进行操作时,实际上会调用魔法方法.也正因为如此,numpy才得以 ...
- Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法
Day09新手小白学python 第九节 Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法 目录 Day09新手小白学python 前言 一.面向对象介绍 二 ...
- 刻意练习:Python基础 -- Task11. 魔法方法
背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...
最新文章
- hibernate总结-N+1问题
- MATLAB 中搭建MatConvNet运行环境(调用GPU运行)以及遇到的错误
- Typora+PicGo+Gitee 图床配置
- 活动、节假日、促销等营销方式的因果效应评估——特征工程篇(一)
- Lucene.Net
- ScriptX打印控件的使用
- 毕设题目:Matlab疾病识别与分类
- Unity自学虚拟摇杆
- 计算理论基础 第2版 Harry R. Lewis 第1章
- BASE16、BASE32、BASE64编码特征及正则匹配
- ABAP 中的搜索帮助
- 关闭mongodb数据库 (netstat -lanp | grep “27017“)
- 大数据常用的开发工具
- Debian 安装手记
- MyBatis中设置事务自动提交
- AI开发者大会,李彦宏成“宏颜获水”?
- 深圳十大绝美看海圣地|深圳海边一日游攻略
- 【洛谷1337】[JSOI2004] 吊打XXX(模拟退火经典题)
- Linux快速入门之 静态库和动态库 (07)
- 软件设计师经典视频教程