当前位置: 首页 > news >正文

python中常用的魔术方法总结(二)

CSDN话题挑战赛第2期
参赛话题:学习笔记

在这里插入图片描述

一、__enter__、__exit__

用于上下文管理器协议

__enter__:进入上下文(with操作对象时)
__exit__:退出上下文(with中的代码块执行完毕之后,执行__exit__()方法)

class MyOpen:
    def __init__(self,filename,mode,encoding='utf-8'):
        self.f=open(filename,mode,encoding=encoding)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()


with MyOpen('1.txt','r',encoding='utf-8') as f:
    res=f.readline()
    print("res",res)

执行结果:
res 666666666


二、__getitem__、__setitem__、__delitem__

__getitem__:实现对索引取值的语法
__setitem__:实现索引赋值的语法(obj[索引]=值)
__delitem__:实现索引删除值得语法

class MyList:
    def __init__(self,*args):
        self.value=list(args)

    def __getitem__(self, item):
        """
        实现对索引取值的支持
        :param item: 索引
        :return:
        """
        return self.value[item]

    def __setitem__(self, key, value):
        """
        实现索引赋值的语法  obbj[索引]=值
        :param key: 索引值
        :param value: 赋的值
        :return:
        """
        self.value[key]=value

    def __delitem__(self, key):
        """
        实现索引删除的值语法  del obj[索引]
        :param key:索引值
        :return:
        """
        del self.value[key]

    def __str__(self):
        return str(self.value)


m1=MyList(11,22,33)

#实现通过索引取值
print(m1[2])    #————》m1.__getitem__(2)

#实现通过索引赋值
m1[0]=666       #————》m1.__setitem__(0,666)
print(m1[0])

#实现通过索引删除值
del m1[0]       #————》m1.__delitem__(0)
print(m1)

执行结果:
33
666
[22, 33]


三、__setattr__、__delattr__、__getattr__、__getattribute__

__setattr__:给对象设置属性
__delattr__:删除对象中的属性
__getattr__:当在__getattribute__(self,item)方法中获取不存在的属性时,到__getatte__(self,item)中触发的属性方法
__getattribute__:获得对象中的属性

class Demo:

    def __setattr__(self, key, value):
        """
        todo setattr(obj,属性名,属性值)
        obj.属性=值
        :param key: 属性名
        :param value: 值
        :return:
        """
        super().__setattr__(key,value)

    def __delattr__(self, key):
        """
        del obj.属性名
        :param key:obj.属性名
        :return:
        """
        super().__delattr__(key)

    def __getattr__(self, item):
        """
        获取属性不存在(__getattribute__)时,触发的属性方法
        :param item:
        :return:
        """
        print('获取属性{}'.format(item))
        return '该属性{}不存在'.format(item)

    def __getattribute__(self, item):
        """
        obj.属性名
        getattr(obj,属性)
        属性获取触发的方法
        :param item:属性名称
        :return:
        """
        return super().__getattribute__(item)


m=Demo()
m.name=99
m.age=18

print(m.__dict__)

del m.age
print(m.__dict__)

print(m.uuuuuu)

执行结果:
—work1----
{‘name’: 99, ‘age’: 18}
{‘name’: 99}
获取属性uuuuuu
该属性uuuuuu不存在

四、自定义一个类

满足以下条件:
1、通过上课的相关知识点对这个类创建的对象,进行属性限制,对象只能设置这个三个属性: title money data
2、通过相关机制对设置的属性类型进行限制,title只能设置字符串类型数据
money设置为int类型数据 data可以设置为任意类型
3、通过相关机制实现,data 属性不能进行删除
4、类支持 obj[属性名] 这种语法获取属性值。

class Demo:
    __slots__ = ['title', 'money', 'data']

    def __init__(self, *args):
        self.title, self.money, self.data = list(args)
        # self.value=list(args)

    # def __init__(self,title,money,data):
    #     self.title=title
    #     self.money=money
    #     self.data=data

    def __setattr__(self, key, value):
        if key == "title":
            if not isinstance(value, str):
                raise ValueError('title只能为字符串')
            else:
                super().__setattr__(key, value)
        elif key == 'money':
            if not isinstance(value, int):
                raise ValueError('money只能设置为int类型')
            else:
                super().__setattr__(key, value)
        else:
            super().__setattr__(key, value)

    def __delattr__(self, item):
        if item == 'data':
            raise ValueError('data不能删除')
        else:
            super().__delattr__(item)

    def __getitem__(self, item):							重要
        return self.__getattribute__(item)					重要


if __name__ == '__main__':
    d = Demo('title1', 120, {"a": 1})
    print(d)
    print(d.title)
    print(d.data)

    d1 = Demo('12', 120, {"a": 1})
    print(d1)
    print(d1.title)

    print(d1["title"])

执行结果:

<main.Demo object at 0x000001E57AB98C40>
title1
{‘a’: 1}
<main.Demo object at 0x000001E57AB98D40>
12
12


在这里插入图片描述

相关文章:

  • 《Autosar_MCAL高阶配置》总目录_培训教程持续更新中...
  • python基础知识点
  • Python的collections原来这么好用
  • Python学习:encode()和decode()方法:字符串编码转换
  • Python深拷贝(deepcopy)、浅拷贝(copy)、等号拷贝的深入理解----看了还不懂找我
  • 【论文研读】-Defining the Ethereum Virtual Machine for Interactive Theorem Provers
  • HIVE 3 使用 MR 引擎多表关联 (JOIN) 导致丢数的问题复现、问题根源及解决方案 (附代码)
  • 计算机毕业设计Java网上求职招聘系统(源码+系统+mysql数据库+Lw文档)
  • C#构造函数
  • 【Node.js+koa--后端管理系统】用户注册接口设计 | 连接Mysql数据库 | 校验注册权限
  • 30岁年薪28W,我还是没顶住压力跳槽了····
  • boost之string_ref
  • Java实现拼图小游戏(1)—— JFrame的认识及界面搭建
  • Java成品网站推荐 毕设从这起步就够了
  • P4 开发实践 — NG-SDN Tutorial — Exercise 5: IPv6 Routing
  • JavaScript-如何实现克隆(clone)函数
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Java IO学习笔记一
  • JavaScript创建对象的四种方式
  • Lucene解析 - 基本概念
  • MySQL-事务管理(基础)
  • nginx 负载服务器优化
  • v-if和v-for连用出现的问题
  • Yii源码解读-服务定位器(Service Locator)
  • 初探 Vue 生命周期和钩子函数
  • 代理模式
  • 关于 Cirru Editor 存储格式
  • 理解在java “”i=i++;”所发生的事情
  • 盘点那些不知名却常用的 Git 操作
  • 前端技术周刊 2019-01-14:客户端存储
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 使用agvtool更改app version/build
  • 手写一个CommonJS打包工具(一)
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 我有几个粽子,和一个故事
  • 进程与线程(三)——进程/线程间通信
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #HarmonyOS:Web组件的使用
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • $NOIp2018$劝退记
  • (06)金属布线——为半导体注入生命的连接
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET中GET与SET的用法
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @Async注解的坑,小心
  • @ModelAttribute使用详解
  • [20170713] 无法访问SQL Server
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [BZOJ3211]:花神游历各国(小清新线段树)
  • [C++]高精度 bign (重载运算符版本)