Python简单魔法方法

说到魔法方法可能和我一样是小白的人没什么印象,但是如果说到Python 类的构建大家都应该能想到下面的函数

class _():
	def __init__(self):
		.......

其实看似简单的类定义实际上暗藏玄机, 其中就蕴含了一个魔法方法:__ init __ 。关于 __ init __ 干什么用的大家也都知道,是在创建对象的时候在初始化被调用,又叫构造函数。其实除了__ init __ 之外还存在不少我们生活中经常遇到但是会完全忽视掉的方法,比如print(dict) print一个对象的时候为甚么就能正确的以字符串形式打印等等,这些都是魔术方法的功劳. 下面会介绍一些常用的方法

  • __ del __ 析构函数:

析构函数是对象在回收的时候所自动调用的函数。说到对象回收会关联到Python的垃圾回收机制,我会在下面的部分写上垃圾回收机制哒。del 函数虽然少见,也很少被显式的写出与调用,却是每个类都有的实实在在存在的重要方法

class _():
    def __init__(self):
        print('我是一个类,如果你看到我了,说明我对象化了')
    @property
    def some_fuc(self):
        print('我被调用了一些方法')
    def __del__(self):
        print('再见了Master, 我换化为资源回到内存当中,请,不要,忘记.....')
if __name__ == '__main__':
    __ = _()
    __.some_fuc
# output
'''
我是一个类,如果你看到我了,说明我对象化了
我被调用了一些方法
再见了Master, 我换化为资源回到内存当中,请,不要,忘记.....
'''

一般来说资源回收这事都是编译器来帮我们做的,但是以后不乏会出现自己需要回收资源的情况:

class _():
    def __init__(self):
        print('我是一个类,如果你看到我了,说明我对象化了')
    @property
    def some_fuc(self):
        print('我被调用了一些方法')

    def __del__(self):
        print('再见了Master, 我换化为资源回到内存当中,请,不要,忘记.....')
if __name__ == '__main__':
    __ = _()
    del __
    __.some_fuc
##output
'''
我是一个类,如果你看到我了,说明我对象化了
再见了Master, 我换化为资源回到内存当中,请,不要,忘记.....
Traceback (most recent call last):
  File "C:/Users/40629/Desktop/some.py", line 87, in <module>
    __.some_fuc
NameError: name '__' is not defined
'''

所以说资源回收函数还是很有用的,因为它,确实帮你回收资源了嘛

  • __ doc __: 代表一个类的文档,主要定义类的说明。怎么用呢,很简单,’’'的注释我之前一直以为不会进入内存中,然而实际上类中的三引号注释会作为说明文档调用

    class _():
        '''
        我是一个可怜弱小有无助的类,哒吖请不要碰伦家
        '''
        def __init__(self):
            print('我是一个类,如果你看到我了,说明我对象化了')
    if __name__ == '__main__':
        __ = _()
        print(__.__doc__)
    # output:
    '''
    我是一个类,如果你看到我了,说明我对象化了
    
        我是一个可怜弱小有无助的类,哒吖请不要碰伦家
    '''
    
  • __ call __ 调用函数。函数调用在任何语言中都是超常用的概念(语言指导:绢旗最爱)。对于Python这种超语法自由的语言,我们甚至可以做到让类像函数一样被调用, 而这正式callable的强大功能

    class sum():
        def __init__(self):
            print("我是一个Object实例")
        def __call__(self, *args, **kwargs):
            count = 0
            for i in args:
                count += i
            return count
    if __name__ == "__main__":
        _ = sum()
        print(_(1,2,3,4,5,6,7))
    
    # output
    '''
    我是一个Object实例
    28
    '''
    
  • __ dict __ 说实话,看到这个方法,我第一眼就是字典。而且事实也确实是这样:__ dict __ 有打印对象所有参数的能力。对于类,dict更能打印所有的包括方法在内的所有属性

    class _():
        def __init__(self):
            print("我是一个Object实例")
            self.name = 'A'
    if __name__ == "__main__":
        __ = sum_
        print(__.__dict__)
        print(_.__dict__)
    # output
    '''
    我是一个Object实例
    {'name': 'A'}
    {'__module__': '__main__', '__init__': <function sum.__init__ at 0x000001E6BBE49280>, '__call__': <function sum.__call__ at 0x000001E6BBE493A0>, '__dict__': <attribute '__dict__' of 'sum' objects>, '__weakref__': <attribute '__weakref__' of 'sum' objects>, '__doc__': None}
    
    '''
    

    不过这就衍生除了Python的权限问题。事实上, dict 可以打印无论共有或私有所有的变量,原因是Python私有变量(self.__ XX)会将访问的名字变化达到无法访问的结果。懂我意思吧,这玩应是有安全隐患的。(这是真的强大)

    class sum():
        def __init__(self):
            print("我是一个Object实例")
            self.name = 'A'
            self.__name = 'A'
        def __call__(self, *args, **kwargs):
            count = 0
            for i in args:
                count += i
            return count
    if __name__ == "__main__":
        _ = sum()
        print(_.__dict__)
    '''
    我是一个Object实例
    {'name': 'A', '_sum__name': 'A'}
    '''
    
  • __ str __ 强转字符串。没啥好说的,在Django中我们就用过哒。当print调用的时候,如果print的对象不是字符串类型就会调用此函数强转。list, tuple, int等等对象都内置了这个方法。对于我这种重度print改bug玩家真的超有用

    class sum():
        def __init__(self):
            print("我是一个Object实例")
        def __str__(self):
            return 'class XX this'
    if __name__ == "__main__":
        n = sum()
        print(n)
    # output
    '''
    我是一个Object实例
    class XX this
    '''
    
  • __ len __ 返回长度,在列表,元组,集合,字符串中都有这玩应。len提供我给们的就是调用可以被len调用返回int的能力。好像也没啥用,但是写出来的代码更符合我们人的逻辑。

    class student():
        def __init__(self):
            self.name = None
            self.age = None
            self.lens = 2
        def __len__(self):
            return self.lens
    if __name__ == '__main__':
        print('学生信息一共要填写', len(student()),'个选项')
    # output
    '''
    学生信息一共要填写 2 个选项
    '''
    
  • __ iterable __ __ next __ 迭代器,不重复,感兴趣看我前面的Python并发2

  • __ getitem __ 这很明显是字典方法的变种,我们按照字典的逻辑去写就可以啦。与之类似的setitem, delitem不过多重复

    class Student():
        def __init__(self):
            self.name = 'A'
            self.age = 10
    
        def __getitem__(self, item):
            if item.lower() == 'name':
                return self.name
            elif item.lower() == 'age':
                return self.age
            else:
                raise KeyError('This key is not one of class Student attr')
    if __name__ == '__main__':
        student = Student()
        print(student['name'],student['age'])
        print(student['id'])
        
    # output
    '''
    A 10
    KeyError: 'This key is not one of class Student attr'
    '''
    

剩下的魔法方法其实有点前篇一律,用的时候再说吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值