2022年 11月 8日

Python基础之内建函数及魔法方法汇总

文章目录

    • 魔法方法
      • 常用场景及释义
        • \_\_new__(cls, [,…])
        • \_\_init__
        • \_\_del__
        • \_\_call__
        • \_\_repr__
        • \_\_str__
        • \_\_bytes__
        • \_\_hash__
        • \_\_bool__
        • \_\_format__
        • \_\_getattr__
        • \_\_getattribute__
        • \_\_setattr__
        • \_\_delattr__
        • __dir__
        • __get__
        • __set__
        • __delete__
        • __it__
        • __le__
        • __eq__
        • __ne__
        • __gt__
        • __ge__
        • __add__
        • __sub__
        • __mul__
        • __truediv__
        • __floordiv__
        • __mod__
        • __divmod__
        • __pow__
      • 自定义容器
        • \_\_getitem__
        • \_\_len__
        • \_\_setitem__(self, key, value)
        • \_\_delitem__(self, key)
        • \_\_iter__(self)
        • \_\_reversed__(self)
        • \_\_contains__(self, item)
        • \_\_missing__(self, key)
      • 上下文管理器(实现了 \_\_enter__和\_\_exit__)
        • \_\_enter__
        • \_\_exit__
      • 对象的序列化
        • TODO
      • 运算符
        • 比较运算符
        • \_\_eq__(self, other)
        • \_\_ne__(self, other)
        • \_\_lt__(self, other)
        • \_\_gt__(self, other)
        • \_\_le__(self, other)
        • \_\_ge__(self, other)
        • 一元运算符
        • \_\_pos__(self)
        • \_\_neg__(self)
        • \_\_dict__
        • \_\_doc__
        • \_\_module__
        • \_\_class__
        • \_\_slots__

魔法方法

常用场景及释义

__new__(cls, [,…])

   __new__才是实例化对象调用的第一个方法,它只取下 cls参数,并把其他参数传给 init

# python2.x单例模式
class Person(object):

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

    def __new__(cls, *args, **kwargs):

        if not hasattr(cls, 'instance'):

            cls.instance = super(Person, cls).__new__(cls)

        return cls.instance

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

__init__

类的初始化操作

  • 1
  • 2

__del__

析构函数  当实例被销毁时自动调用

  • 1
  • 2

__call__

允许一个类的实例像函数一样被调用
实例被call时候自动调用

  • 1
  • 2
  • 3

__repr__

repr('') 时使用,返回一个方便计算机看的字符串(代表该实例)

  • 1
  • 2

__str__

basestring子类
str('')时使用, 返回一个方便人看的字符串(代表该实例)

  • 1
  • 2
  • 3

__bytes__

bytes() 时候调用,必须返回一个 bytes值,否则会报错的

'TypeError: __bytes__ returned non-bytes (type str)'

  • 1
  • 2
  • 3
  • 4

__hash__

hash()
  • 1

__bool__

bool()
  • 1

__format__

__format__(self, formatstr)

^, <, > 分别是居中、左对齐、右对齐,后面带宽度, : 号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。

+ 表示在正数前显示 +,负数前显示 -;  (空格)表示在正数前加空格

b、d、o、x 分别是二进制、十进制、八进制、十六进制。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

__getattr__

定义当用户试图访问一个不存在属性的时候的行为

  • 1
  • 2

__getattribute__

定义属性被访问时候的行为(属性被访问实际动作)
#注意此处不要用 self.__dict__[item]
#因为self.__dict__依然会被__getattribute__拦截 这样就会陷入循环

  • 1
  • 2
  • 3
  • 4

__setattr__

 定义当一个属性被设置的时候的行为


  • 1
  • 2
  • 3

__delattr__

定义当一个属性被删除的时候的行为

  • 1
  • 2

dir


  • 1

get


  • 1

set


  • 1

delete


  • 1

it



  • 1
  • 2

le



  • 1
  • 2

eq


  • 1

ne


  • 1

gt

    ge

      add

        sub

        
        
        • 1

        mul

        
        
        • 1

        truediv

        
        
        • 1

        floordiv

        
        
        • 1

        mod

          divmod

          
          
          
          • 1
          • 2

          pow

            自定义容器


            • demo
              class Task:
              """
              任务封包
              任务划定为: 每个tab的串行 一个tab 及下行数据 是一个任务
              """
              
              __slots__ = ["tag", "panel", "block", "timestamp", "status"]
              
              def __init__(self):
                  self.tag = None
                  self.panel = None
                  self.block = None
                  self.timestamp = int(time.time())
                  self.status = 0
              
              def __setitem__(self, key, value):
                  setattr(self, key, value)
              
              def __getitem__(self, item):
                  return getattr(self, item)
              
              def keys(self):
                  return self.__slots__
              
              
              • 1
              • 2
              • 3
              • 4
              • 5
              • 6
              • 7
              • 8
              • 9
              • 10
              • 11
              • 12
              • 13
              • 14
              • 15
              • 16
              • 17
              • 18
              • 19
              • 20
              • 21
              • 22
              • 23
              • 24

            __getitem__

            __getitem__ 定义获取容器中指定元素的行为,相当于self[key]
            
            • 1

            __len__

            return 数值 标识容器长度 len() 自动调用
            
            
            • 1
            • 2

            __setitem__(self, key, value)

            
            self[key] = value时自动调用的该方法。
            
            
            • 1
            • 2
            • 3

            __delitem__(self, key)

            del self[key]的时自动调用的该方法。
            
            • 1

            __iter__(self)

            return iterator  
            for x in container:iter(container)时自动调用。
            
            • 1
            • 2
            • 3

            __reversed__(self)

            內建函数reversed()自动调用该方法====
            • 1

            __contains__(self, item)

            如果定义了该方法,那么在执行item in container 或者 item not in container时该方法就会被调用。
            如果没有定义,那么Python会迭代容器中的元素来一个一个比较,从而决定返回True或者False
            • 1
            • 2
            • 3

            __missing__(self, key)

            dict字典类型会有该方法,它定义了key如果在容器中找不到时触发的行为。
            比如d = {'a': 1}, 当你执行d[notexist]时,d.__missing__('notexist')就会被调用。\
            
            • 1
            • 2

            上下文管理器(实现了 __enter__和__exit__)

            形如:
            with open('1.txt', 'w') as file:
                pass
            
            • 1
            • 2
            • 3

            __enter__

            __enter__会返回一个值,并赋值给as关键词之后的变量。在这里,你可以定义代码段开始的一些操作。
            
            
            • 1
            • 2

            __exit__

            __exit__(self, exception_type, exception_value, traceback)
            
            __exit__定义了代码段结束后的一些操作,可以这里执行一些清除操作,或者做一些代码段结束后需要立即执行的命令,比如文件的关闭,socket断开等。如果代码段成功结束,那么exception_type, exception_value, traceback 三个参数传进来时都将为None。如果代码段抛出异常,那么传进来的三个参数将分别为: 异常的类型,异常的值,异常的追踪栈。
            如果__exit__返回True, 那么with声明下的代码段的一切异常将会被屏蔽。
            如果__exit__返回None, 那么如果有异常,异常将正常抛出,这时候with的作用将不会显现出来。
            
            • 1
            • 2
            • 3
            • 4
            • 5

            对象的序列化


                 对象的反序列化操作必须要求序列化时, 有序列化时的类存在 比如 <__main__.Class >

            TODO

            Python对象的序列化操作是pickling进行的。pickling非常的重要,以至于Python对此有单独的模块pickle,还有一些相关的魔术方法。使用pickling, 你可以将数据存储在文件中,之后又从文件中进行恢复。
            
            下面举例来描述pickle的操作。从该例子中也可以看出,如果通过pickle.load 初始化一个对象, 并不会调用__init__方法。
            
            # -*- coding: utf-8 -*-
            from datetime import datetime
            import pickle
            
            classDistance(object):
            
                def__init__(self, meter):
                    print 'distance __init__'
                    self.meter = meter
            
            data = {
                'foo': [1, 2, 3],
                'bar': ('Hello', 'world!'),
                'baz': True,
                'dt': datetime(2016, 10, 01),
                'distance': Distance(1.78),
            }
            print 'before dump:', data
            with open('data.pkl', 'wb') as jar:
                pickle.dump(data, jar)  # 将数据存储在文件中
            
            del data
            print 'data is deleted!'
            
            with open('data.pkl', 'rb') as jar:
                data = pickle.load(jar)  # 从文件中恢复数据
            print 'after load:', data
            值得一提,从其他文件进行pickle.load操作时,需要注意有恶意代码的可能性。另外,Python的各个版本之间,pickle文件可能是互不兼容的。
            
            pickling并不是Python的內建类型,它支持所有实现pickle协议(可理解为接口)的类。pickle协议有以下几个可选方法来自定义Python对象的行为。
            
            __getinitargs__(self)
            
            如果你希望unpickle时,__init__方法能够调用,那么就需要定义__getinitargs__, 该方法需要返回一系列参数的元组,这些参数就是传给__init__的参数。
            
            该方法只对old-style class有效。所谓old-style class,指的是不继承自任何对象的类,往往定义时这样表示: class A:, 而非class A(object):
            
            __getnewargs__(self)
            
            跟__getinitargs__很类似,只不过返回的参数元组将传值给__new__
            
            __getstate__(self)
            
            在调用pickle.dump时,默认是对象的__dict__属性被存储,如果你要修改这种行为,可以在__getstate__方法中返回一个state。state将在调用pickle.load时传值给__setstate__
            
            __setstate__(self, state)
            
            一般来说,定义了__getstate__,就需要相应地定义__setstate__来对__getstate__返回的state进行处理。
            
            __reduce__(self)
            
            如果pickle的数据包含了自定义的扩展类(比如使用C语言实现的Python扩展类)时,就需要通过实现__reduce__方法来控制行为了。由于使用过于生僻,这里就不展开继续讲解了。
            
            令人容易混淆的是,我们知道, reduce()是Python的一个內建函数, 需要指出__reduce__并非定义了reduce()的行为,二者没有关系。
            
            __reduce_ex__(self)
            
            __reduce_ex__ 是为了兼容性而存在的, 如果定义了__reduce_ex__, 它将代替__reduce__ 执行。
            
            下面的代码示例很有意思,我们定义了一个类Slate(中文是板岩的意思)。这个类能够记录历史上每次写入给它的值,但每次pickle.dump时当前值就会被清空,仅保留了历史。
            
            # -*- coding: utf-8 -*-
            import pickle
            import time
            
            classSlate:
                '''Class to store a string and a changelog, and forget its value when pickled.'''
                def__init__(self, value):
                    self.value = value
                    self.last_change = time.time()
                    self.history = []
            
                defchange(self, new_value):
                    # 修改value, 将上次的valeu记录在history
                    self.history.append((self.last_change, self.value))
                    self.value = new_value
                    self.last_change = time.time()
            
                defprint_changes(self):
                    print 'Changelog for Slate object:'
                    for k, v in self.history:
                        print '%s    %s' % (k, v)
            
                def__getstate__(self):
                    # 故意不返回self.value和self.last_change,
                    # 以便每次unpickle时清空当前的状态,仅仅保留history
                    return self.history
            
                def__setstate__(self, state):
                    self.history = state
                    self.value, self.last_change = None, None
            
            slate = Slate(0)
            time.sleep(0.5)
            slate.change(100)
            time.sleep(0.5)
            slate.change(200)
            slate.change(300)
            slate.print_changes()  # 与下面的输出历史对比
            with open('slate.pkl', 'wb') as jar:
                pickle.dump(slate, jar)
            del slate  # delete it
            with open('slate.pkl', 'rb') as jar:
                slate = pickle.load(jar)
            print 'current value:', slate.value  # None
            print slate.print_changes()  # 输出历史记录与上面一致
            
            
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20
            • 21
            • 22
            • 23
            • 24
            • 25
            • 26
            • 27
            • 28
            • 29
            • 30
            • 31
            • 32
            • 33
            • 34
            • 35
            • 36
            • 37
            • 38
            • 39
            • 40
            • 41
            • 42
            • 43
            • 44
            • 45
            • 46
            • 47
            • 48
            • 49
            • 50
            • 51
            • 52
            • 53
            • 54
            • 55
            • 56
            • 57
            • 58
            • 59
            • 60
            • 61
            • 62
            • 63
            • 64
            • 65
            • 66
            • 67
            • 68
            • 69
            • 70
            • 71
            • 72
            • 73
            • 74
            • 75
            • 76
            • 77
            • 78
            • 79
            • 80
            • 81
            • 82
            • 83
            • 84
            • 85
            • 86
            • 87
            • 88
            • 89
            • 90
            • 91
            • 92
            • 93
            • 94
            • 95
            • 96
            • 97
            • 98
            • 99
            • 100
            • 101
            • 102
            • 103
            • 104
            • 105
            • 106
            • 107
            • 108
            • 109
            • 110
            • 111

            运算符


            比较运算符

            __eq__(self, other)

            定义了比较操作符==的行为.
            
            • 1

            __ne__(self, other)

            定义了比较操作符!=的行为.
            
            • 1

            __lt__(self, other)

            定义了比较操作符<的行为.
            
            • 1

            __gt__(self, other)

            定义了比较操作符>的行为.
            
            • 1

            __le__(self, other)

            定义了比较操作符<=的行为.
            
            • 1

            __ge__(self, other)

            定义了比较操作符>=的行为.
            
            • 1

            一元运算符

            __pos__(self)

            实现了'+'号一元运算符(比如+some_object)
            
            • 1

            __neg__(self)

            实现了'-'号一元运算符(比如-some_object)
            
            • 1

            link

            ## 魔法属性

            __dict__

            类的__dict__属性存储了类定义的所有类属性、类方法等组成的键值对,但不包括继承而来的属性和方法
            
            实例的__dict__属性存储了所有的实例属性的键值对,如果没有就为空;__init__方法其实就是对__dict__属性的初始化赋值;
            
            • 1
            • 2
            • 3

            __doc__

            该属性记录了类的说明文档,用类和实例引用指向的都是类的__doc__属性,如果没有默认为None
            • 1

            __module__

            该属性记录类定义的位置,如果定义的位置正好是主程序,那么该值为"_main_",否则是类属于的模块的名字;
            
            • 1

            __class__

            该属性指向该实例的类,即实例指向类对象,类对象指向元类;
            
            • 1

            __slots__

            该属性起到限制动态绑定属性和方法的作用,该属性是一个元组,默认是不存在的,需要手动定义并且只对当前的类起作用,只有添加到元组中的名字才能被动态添加属性,否则报错!
            
            • 1