主页

索引

模块索引

搜索页面

魔法方法

定义:

魔法方法总是被双下划线包围,例如__init__
魔法方法的第一个参数应为cls(类方法) 或者self(实例方法)
    cls:代表一个类的名称
    self:代表一个实例对象的名称

基本魔法方法

__init__(self[, …]):

构造器,当一个实例被创建的时候调用的初始化方法

__new__(cls[, …]):

在一个对象实例化的时候所调用的第一个方法
在调用__init__初始化前,先调用__new__

备注

__new__() 是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 __init__() 初始化方法被调用。

实例:

class A(object):
    def __init__(self, value):
        print("into A __init__")
        self.value = value

    def __new__(cls, *args, **kwargs):
        print("into A __new__")
        print(cls)
        return object.__new__(cls)


class B(A):
    def __init__(self, value):
        print("into B __init__")
        self.value = value

    def __new__(cls, *args, **kwargs):
        print("into B __new__")
        print(cls)
        return super().__new__(cls, *args, **kwargs)


b = B(10)

# 结果:
# into B __new__
# <class '__main__.B'>
# into A __new__
# <class '__main__.B'>
# into B __init__

利用__new__实现单例模式:

# 1. 普通方案
class Earth:
    pass

a = Earth()
print(id(a))  # 260728291456
b = Earth()
print(id(b))  # 260728291624


# 2. 单例方案
class Earth:
    __instance = None  # 定义一个类属性做判断

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance

a = Earth()
print(id(a))  # 512320401648
b = Earth()
print(id(b))  # 512320401648

_del__(self):

析构器,当一个对象将要被系统回收之时调用的方法

__str__(self):

当你打印一个对象的时候,触发__str__
当你使用%s格式化的时候,触发__str__
str强转数据类型的时候,触发__str__

__repr__(self):

repr是str的备胎
有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
repr(obj)内置函数对应的结果是__repr__的返回值
当你使用%r格式化的时候 触发__repr__

备注

__str__(self) 的返回结果可读性强。也就是说,__str__ 的意义是得到便于人们阅读的信息,就像下面的 ‘2019-10-11’ 一样。__repr__(self) 的返回结果应更准确。怎么说,__repr__ 存在的目的在于调试,便于开发者使用。

运算符

算术运算符:

方法名                         使用
__add__(self, other)        self + other
__sub__(self, other)        self - other
__mul__(self, other)        self * other
__floordiv__(self, other)   self // other
__truediv__(self, other)    self / other
__mod__(self, other)        self % other
__pow__(self, other)        self ** other

__lshift__(self, other)         <<
__rshift__(self, other)         >>
__and__(self, other)            &
__xor__(self, other)            ^
__or__(self, other)             |

反算术运算符:

说明:
    反运算魔方方法,与算术运算符保持一一对应,不同之处就是反运算的魔法方法多了一个“r”。
    当文件左操作不支持相应的操作时被调用。
实例说明:
    >>> a + b
    这里加数是a,被加数是b,因此是a主动,
    反运算就是如果a对象的__add__()方法没有实现或者不支持相应的操作,
    那么 Python 就会调用b的__radd__()方法

__radd__(self, other)
__rsub__(self, other)
__rmul__(self, other)
__rtruediv__(self, other)
__rfloordiv__(self, other)
__rmod__(self, other)
__rdivmod__(self, other)
__rpow__(self, other[, module])
__rlshift__(self, other)
__rrshift__(self, other)
__rand__(self, other)
__rxor__(self, other)
__ror__(self, other)

增量赋值运算符:

__iadd__(self, other)           +=
__isub__(self, other)           -=
__imul__(self, other)           *=
__itruediv__(self, other)       /=
__ifloordiv__(self, other)      //=
__imod__(self, other)           %=
__ipow__(self, other[, modulo])     **=
__ilshift__(self, other)            <<=
__irshift__(self, other)            >>=
__iand__(self, other)       &=
__ixor__(self, other)       ^=
__ior__(self, other)        |=

一元运算符:

__neg__(self)       定义正号的行为:+x
__pos__(self)       定义负号的行为:-x
__abs__(self)       定义当被abs()调用时的行为
__invert__(self)    定义按位求反的行为:~x

比较函数

方法名称                       使用
__eq__(self, other)         self == other
__ne__(self, other)         self != other
__lt__(self, other)         self < other
__gt__(self, other)         self > other
__le__(self, other)         self <= other
__ge__(self, other)         self >= other

采用一般方法写法:

class Word():
    def __init__(self, text):
        self.text = text

    def equals(self, word2):
        return self.text.lower() == word2.text.lower()

#创建3个字符Object
first = Word('ha')
second = Word('HA')
third = Word('eh')

#进行比较
first.equals(second)  #True
first.equals(third)   #False

采用特殊方法写法:

class Word():
    def __init__(self, text):
        self.text = text

    def __eq__(self, word2):
        return self.text.lower() == word2.text.lower()

#创建3个字符对象
first = Word('ha')
second = Word('HA')
third = Word('eh')

#进行比较
first == second  #True
first == third   #False

属性访问

__getattr__(self, name):

定义当用户试图获取一个不存在的属性时的行为。
使用x[key]索引操作符的时候调用

__getattribute__(self, name):

定义当该类的属性被访问时的行为
(先调用该方法,查看是否存在该属性,若不存在,接着去调用__getattr__)。

__setattr__(self, name, value):

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

__delattr__(self, name):

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

实例:

class C:
    def __getattribute__(self, item):
        print('__getattribute__')
        return super().__getattribute__(item)

    def __getattr__(self, item):
        print('__getattr__')

    def __setattr__(self, key, value):
        print('__setattr__')
        super().__setattr__(key, value)

    def __delattr__(self, item):
        print('__delattr__')
        super().__delattr__(item)


c = C()
c.x
# __getattribute__
# __getattr__

c.x = 1
# __setattr__

del c.x
# __delattr__

描述符

描述符就是将某种特殊类型的类的实例指派给另一个类的属性。

__get__(self, instance, owner)用于访问属性,它返回属性的值。
__set__(self, instance, value)将在属性分配操作中调用,不返回任何内容。
__del__(self, instance)控制删除操作,不返回任何内容。

实例:

class MyDecriptor:
    def __get__(self, instance, owner):
        print('__get__', self, instance, owner)

    def __set__(self, instance, value):
        print('__set__', self, instance, value)

    def __delete__(self, instance):
        print('__delete__', self, instance)


class Test:
    x = MyDecriptor()


t = Test()

1. 调用__get__方法
t.x
# __get__ <__main__.MyDecriptor object at 0x7f8cd81ae650> <__main__.Test object at 0x7f8cd81ae290> <class '__main__.Test'>


2. 调用__set__方法
t.x = 'x-man'
# __set__ <__main__.MyDecriptor object at 0x7f8cd81ae650> <__main__.Test object at 0x7f8cd81ae290> x-man

3. 删除__delete__方法
del t.x
# __delete__ <__main__.MyDecriptor object at 0x7f8cd81ae650> <__main__.Test object at 0x7f8cd81ae290>

定制序列

__len__(self):

对序列对象使用内建的len()函数的时候调用
__len__(self)     len(self)

__getitem__(self, key):

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

__setitem__(self, key, value):

定义设置容器中指定元素的行为,相当于
>>> self[key] = value

__delitem__(self, key):

定义删除容器中指定元素的行为,相当于
>>> del self[key]

【例子】编写一个可改变的自定义列表,要求记录列表中每个元素被访问的次数:

class CountList:
    def __init__(self, *args):
        self.values = [x for x in args]
        self.count = {}.fromkeys(range(len(self.values)), 0)

    def __len__(self):
        return len(self.values)

    def __getitem__(self, item):
        self.count[item] += 1
        return self.values[item]

    def __setitem__(self, key, value):
        self.values[key] = value

    def __delitem__(self, key):
        del self.values[key]
        for i in range(0, len(self.values)):
            if i >= key:
                self.count[i] = self.count[i + 1]
        self.count.pop(len(self.values))


c1 = CountList(1, 3, 5, 7, 9)
c2 = CountList(2, 4, 6, 8, 10)
print(c1[1])  # 3
print(c2[2])  # 6
c2[2] = 12
print(c1[1] + c2[2])  # 15
print(c1.count)
# {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
print(c2.count)
# {0: 0, 1: 0, 2: 2, 3: 0, 4: 0}
del c1[1]
print(c1.count)
# {0: 0, 1: 0, 2: 0, 3: 0}

迭代器

迭代器有两个基本的方法:

iter(object)    函数用来生成迭代器
next(iterator[, default])   返回迭代器的下一个项目

实例:

links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}

it = iter(links)
while True:
    try:
        each = next(it)
    except StopIteration:
        break
    print(each)
# B
# A
# T

it = iter(links)
print(next(it))  # B
print(next(it))  # A
print(next(it))  # T
print(next(it))  # StopIteration Exception

实例:

class Fibs:
    def __init__(self, n=10):
        self.a = 0
        self.b = 1
        self.n = n

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.n:
            raise StopIteration
        return self.a

fibs = Fibs(100)
for each in fibs:
    print(each, end=' ')

# 1 1 2 3 5 8 13 21 34 55 89

生成器

备注

在 Python 中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。

【例子】用生成器实现斐波那契数列:

def libs(n):
    a = 0
    b = 1
    while True:
        a, b = b, a + b
        if a > n:
            return
        yield a


for each in libs(100):
    print(each, end=' ')

# 1 1 2 3 5 8 13 21 34 55 89

主页

索引

模块索引

搜索页面