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


物联沃分享整理
物联沃-IOTWORD物联网 » python中常用的魔术方法总结(二)

发表评论