python魔术方法(持续添加)

前言

python有很多魔术方法,用的时候到处查,就想着写个博客记录一下吧

魔术方法

init

这个方法我认为就相当于构造方法,用于初始化类,在实例化的时候调用,传入的参数一般就是对应的对象的属性

class Person:
	def __init__(self, name, age):
		self.name = name
		self.age = age

p = Person('cgy', 19)
print(p.name, p.age) # cgy 19

del

这个方法就是析构方法,在对象被销毁的时候调用(1. del关键字 2. 程序结束后)

del
class Person:
	def __del__(self):
		print('对象被销毁')

p = Person()
del p # 对象被销毁
print('flag')

会发现在打印flag之前,会打印"对象被销毁",就是说,在del p的时候,对象确实被销毁了

程序结束时

这里用到了一个atexit模块,他可以在程序结束时做一些事情

import atexit


atexit.register(lambda x: print(x), '程序结束了')
class Person
	def __del__(self):
		print('对象被销毁')

p = Person()

会发现打印顺序是1. 程序结束了,2. 对象被销毁,就是说程序结束之后在清空程序用到的内存的时候,才打印出了“对象被销毁”这句话

getitem

在像字典一样获取元素时调用

setitem

在像字典一样设置属性时调用

delitem

在像字典一样删除元素时调用
这三个魔术方法可以让对象跟字典一样使用,而字典类似于js里面的对象,所以我觉得就是使得python的对象能够跟js里面的对象有共同的表现形式的方法。

class Animal(object):
    def __getitem__(self, item):
        print('__getitem__ ', item)
        return self.__dict__.get(item)

    def __setitem__(self, key, value):
        print('__setitem__', key, ': ', value)
        self.__dict__[key] = value
        
    def __delitem__(self, key):
        print('__delitem__')
        del self.__dict__[key]
a = Animal()
a['name'] = 'cgy'
print(a['name']) 
del a['name']

在上面的代码中,除了实例化的a = Animal(),其他三行代码分别调用了__setitem__、__ getitem__、__delitem __。而且只有在像字典一样使用这个对象的时候,才会调用这几个方法,如果是a.name = 'cgy'print(a.name)del a.name,这样子是不会调用这几个方法的。但是如print(a.name)是可以获取到cgy这个字符串的。

然后,我个人认为就是,__delitem__这个方法,是可以保证程序正常运行的一个方法,使得我们在错误删除属性的时候,程序还是可以正常运行,可以在里面使用try…except…语句,然后抓住异常,进行处理,即:如果没有这样的属性名,打印提示信息

    def __delitem__(self, key):
        try:
            del self.__dict__[key]
        except KeyError as e:
            print('there is no key called', e)

getattr

获取属性的时候,如果对象没有这个属性,调用这个方法

setattr

每次设置属性的时候,调用这个方法包括__init__

delattr

删除属性的时候,调用这个方法

class Animal:
	def __init__(self, name):
		self.name = name
		
    def __getattr__(self, item):
        # 在获取__没有定义__的属性的时候,调用这个方法
        print(f'you want attribute "{item}", but "{item}" is not defined')

    def __setattr__(self, key, value):
        # 设置属性的时候,调用这个方法
        print('__setattr__ ', key, ': ', value)
        self.__dict__[key] = value

    def __delattr__(self, item):
        print('__delattr__')
        try:
            del self.__dict__[item]
        except KeyError as e:
            print('there is no key called', e)

a = Animal('cgy')
a.age = 19
print(a.age)
del a.name

上面这段程序,在实例化的那一行,执行了__init__构造方法,会调用一次__setattr__;a.age = 19会再一次调用__setattr__;在print(a.age)因为获取了a.age,所以会调用一次__getattr__;最后的del a.name会调用__delattr__

我觉得需要区分的是,如果这个类中也有__setitem__等魔术方法,我们像字典一样操作对象的时候,这些__setattr__等方法是不会被调用的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gsxdcyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值