Python语法基础之. Task11 魔法方法(15-16/17)

0. 基本概念

魔法方法总是被双下划线包围,例如__init__

他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。

魔法方法的“魔力”体现在它们总能够在适当的时候被自动调用。

魔法方法的第一个参数应为cls(类方法) 或者self(实例方法)。

  • cls:代表一个类的名称
  • self:代表一个实例对象的名称

1. 从最基础的魔法方法开始

1.1 init__(self[, ...])

  • 构造器,当一个实例被创建的时候调用的初始化方法
class Rectangle:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def getPeri(self):
        return (self.x + self.y) * 2

    def getArea(self):
        return self.x * self.y

rect = Rectangle(7, 8)
# 可以使得代码大幅缩短
print(rect.getPeri())  # 30
print(rect.getArea())  # 56

1.2 __new__(cls[, ...])

  • __new__ 是在一个对象实例化的时候所调用的第一个方法,在调用 __init__初始化前,先调用__new__
  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__
  • __new__对当前类进行了实例化,并将实例返回,传给__init__self。但是,执行了__new__,并不一定会进入__init__,只有__new__返回了,当前类cls的实例,当前类的__init__才会进入。
# Sample 1:
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(1)
# 结果:
# into B __new__
# <class '__main__.B'>
# into A __new__
# <class '__main__.B'>
# into B __init__

# Sample 2: 
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__(A, *args, **kwargs)  # 改动了cls变为A

b = B(1)
# 结果:
# into B __new__
# <class '__main__.B'>
# into A __new__
# <class '__main__.A'>

不一样的是:

  • __new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行 ==> 将没有__init__被调用。
  • 可利用__new__实现单例模式。
class Earth:
    pass

# 使用 id() 会返回随机的数值
a = Earth()
print(id(a))  # 4395696424
b = Earth()
print(id(b))  # 4395696480
# 两次的数值不同


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))  # 4395696536
b = Earth()
print(id(b))  # 4395696536
# 两次的数值相同,因为返回的是同一个实例———>单例
  • __new__方法主要作用是:当继承一些不可变的 class 时(比如int, str, tuple), 提供一个自定义这些类的实例化过程的途径。
class ToCapStr(str):
    def __new__(cls, string):
        string = string.upper()
        return str.__new__(cls, string)

a = ToCapStr("You can see tHat aLl letters become Capital one")
print(a)  # YOU CAN SEE THAT ALL LETTERS BECOME CAPITAL ONE

1.3 __del__(self)

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

Python 采用自动引用计数(ARC)方式来回收对象所占用的空间,当程序中有一个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 1;当程序中有两个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 2,依此类推,如果一个对象的引用计数变成了 0,则说明程序中不再有变量引用该对象,表明程序不再需要该对象,因此 Python 就会回收该对象。

大部分时候,Python 的 ARC 都能准确、高效地回收系统中的每个对象。但如果系统中出现循环引用的情况,比如对象 a 持有一个实例变量引用对象 b,而对象 b 又持有一个实例变量引用对象 a,此时两个对象的引用计数都是 1,而实际上程序已经不再有变量引用它们,系统应该回收它们,此时 Python 的垃圾回收器就可能没那么快,要等专门的循环垃圾回收器(Cyclic Garbage Collector)来检测并回收这种引用循环。

class C(object):
    def __init__(self):
        print('into C __init__')

    def __del__(self):
        print('into C __del__')


c1 = C()
# into C __init__
c2 = c1
c3 = c2
del c3
del c2
del c1
# into C __del__
class C(object):
    def __init__(self):
        print('into C __init__')

    def __del__(self):
        print('into C __del__')


c1 = C()
c2 = C()
# into C __init__
# into C __init__
# into C __del__
# into C __del__

然而我本地实现的结果是这样的。实例化的时候就已经打印方法了。

1.4 __str____repr__

__str__(self):

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

__repr__(self):

  • __repr____str__的备胎
  • __str__的时候执行_str_,没有实现_str_的时候,执行`repr```
  • __repr(obj)__内置函数对应的结果是__repr__的返回值
  • 当使用%r格式化的时候,触发__repr__
class Dog:
    """定义一个狗类"""
    def __init__(self, new_name, new_age):
        """在创建完对象之后会自动调用, 完成对象的初始化的功能"""
        self.name = new_name
        self.age = new_age

    def __str__(self):
        """返回一个对象的描述信息"""
        return "名字是:%s , 年龄是:%d" % (self.name, self.age)

    def __repr__(self):
        """返回一个对象的描述信息"""
        return "Cat:(%s,%d)" % (self.name, self.age)

    def eat(self):
        print("%s在吃肉...." % self.name)

    def drink(self):
        print("%s在喝可乐..." % self.name)

    def introduce(self):
        print("名字是:%s, 年龄是:%d" % (self.name, self.age))

tom = Dog("Max", 10)
print(tom)        # 名字是:Max , 年龄是:10
print(str(tom))   # 名字是:Max , 年龄是:10
print(repr(tom))  # Cat:(Max,10)
tom.eat()         # Max在吃肉....
tom.introduce()   # 名字是:Max, 年龄是:10
import datetime

today = datetime.date.today()
print(str(today))   # 2019-11-04
print(repr(today))  # datetime.date(2019, 11, 4)
print('%s' %today)  # 2019-11-04
print('%r' %today)  # datetime.date(2019, 11, 4)

可以这样理解:

__str__(self) 的返回结果可读性强。__str__ 便于人们阅读信息。

__repr__(self) 的返回结果应更准确。__repr__ 更为程序化的语言,便于调试。

2. 算术运算符

类似工厂函数,指的是不通过类而是通过函数来创建对象。

补充:两篇关于工厂函数的博文 博文1博文2

class C:
    pass

print(type(len))  # <class 'builtin_function_or_method'>
print(type(dir))  # <class 'builtin_function_or_method'>
print(type(int))  # <class 'type'>
print(type(list))  # <class 'type'>
print(type(tuple))  # <class 'type'>

print(type(C))  # <class 'type'>
print(int('123'))  # 123

# 这个例子中list工厂函数把一个元祖对象加工成了一个列表对象。
print(list((1, 2, 3)))  # [1, 2, 3]
  • __add(self, other)__定义加法的行为:+
  • __sub(self, other)__定义减法的行为:-
class MyClass:

    def __init__(self, height, weight):
        self.height = height
        self.weight = weight

    # 两个对象的长相加,宽不变;但返回一个新的类
    def __add__(self, others):
        return MyClass(self.height + others.height, self.weight + others.weight)

    # 两个对象的宽相减,长不变;但返回一个新的类
    def __sub__(self, others):
        return MyClass(self.height - others.height, self.weight - others.weight)

    # 参数定义
    def intro(self):
        print("Height is", self.height, " Weight is", self.weight)


def main():
    a = MyClass(height=20, weight=10)
    a.intro()

    b = MyClass(height=30, weight=15)
    b.intro()

    # 参数'-'运算,产生新的对象
    c = b - a
    c.intro()

    # 参数'+'运算,产生新的对象
    d = a + b
    d.intro()

main()

# Height is 20  Weight is 10
# Height is 30  Weight is 15
# Height is 10  Weight is 5
# Height is 50  Weight is 25

其他的:

  • __mul__(self, other)定义乘法的行为:*
  • __truediv__(self, other)定义真除法的行为:/
  • __floordiv__(self, other)定义整数除法的行为://
  • __mod__(self, other) 定义取模算法的行为:%
  • __divmod__(self, other)定义当被 divmod() 调用时的行为
  • __divmod__(a, b)把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
print(divmod(11, 3))  # (3, 2)
print(divmod(10, 2))  # (5, 0)
  • __pow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
  • __lshift__(self, other)定义按位左移位的行为:<<
  • __rshift__(self, other)定义按位右移位的行为:>>
  • __and__(self, other)定义按位与操作的行为:&
  • __xor__(self, other)定义按位异或操作的行为:^
  • __or__(self, other)定义按位或操作的行为:|

这些算术运算符的对应的工厂方法也是可以直接调用的。

3. 反算术运算符

反运算魔方方法,与算术运算符保持一一对应。

不同之处在于:反运算的魔法方法多了一个“r”字母。注意:当文件左操作不支持相应的操作时被调用。

  • __radd__(self, other)定义加法的行为:+
  • __rsub__(self, other)定义减法的行为:-
  • __rmul__(self, other)定义乘法的行为:*
  • __rtruediv__(self, other)定义真除法的行为:/
  • __rfloordiv__(self, other)定义整数除法的行为://
  • __rmod__(self, other) 定义取模算法的行为:%
  • __rdivmod__(self, other)定义当被 divmod() 调用时的行为
  • __rpow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为
  • __rlshift__(self, other)定义按位左移位的行为:<<
  • __rrshift__(self, other)定义按位右移位的行为:>>
  • __rand__(self, other)定义按位与操作的行为:&
  • __rxor__(self, other)定义按位异或操作的行为:^
  • __ror__(self, other)定义按位或操作的行为:|

对于a + b:

这里加数是a,被加数是b,因此是a主动,反运算就是如果a对象的__add__()方法没有实现或者不支持相应的操作,那么 Python 就会调用b__radd__()方法。

class letterRint(int):
    def __radd__(self, other):
        """若是被加数,实际返回减法"""
        return int.__sub__(other, self)  # 特别注意:self 在后面!

a = letterRint(5)
b = letterRint(3)
print(a + b)  # 8
print(1 + b)  # -2

4. 增量赋值运算符

  • __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)定义赋值按位或操作的行为:|=

5. 一元运算符

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

6. 属性访问

__getattr____getattribute____setattr____delattr__

__getattr__(self, name): 定义当用户试图获取一个不存在的属性时的行为。

__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__

同样的,还是因为编译器?类的实例化的时候就直接打印信息了

Python魔法方法之属性访问详解

7. 描述符

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

  • __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()
t.x
# ____get__ <__main__.MyDecriptor object at 0x105fce518> <__main__.Test object at 0x105fce550> <class '__main__.Test'>

t.x = 'x-man'
# __set__ <__main__.MyDecriptor object at 0x105fce518> <__main__.Test object at 0x105fce550> x-man

del t.x
# __delete__ <__main__.MyDecriptor object at 0x105fce518> <__main__.Test object at 0x105fce550>

Python的描述符

8. 定制序列

协议(Protocols)与其它编程语言中的接口很相似,它规定你哪些方法必须要定义。然而,在 Python 中的协议就显得不那么正式。事实上,在 Python 中,协议更像是一种指南。

容器类型的协议:

  • 如果希望定制的容器是不可变的话,只需要定义__len__()__getitem()__方法。
  • 如希望定制的容器是可变的话,除了__len__()__getitem__()方法,还需要定义__setitem__()__delitem()__两个方法。

Sample 1:

编写一个不可改变的自定义列表,并记录列表中每个元素被访问的次数。

class StableList:
    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]


c1 = StableList(1, 3, 5, 7, 9)
c2 = StableList(1, 1, 2, 3, 5, 8, 11)
print(c1[1])  # 3
print(c2[2])  # 2
print(c1[1] + c2[1])  # 4

print(c1.count)
# {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}

print(c2.count)
# {0: 0, 1: 1, 2: 1, 3: 0, 4: 0, 5: 0, 6: 0}
  • __len__(self)定义当被len()调用时的行为(返回容器中元素的个数)。
  • __getitem__(self, key)定义获取容器中元素的行为,相当于self[key]
  • __setitem__(self, key, value)定义设置容器中指定元素的行为,相当于self[key] = value
  • __delitem__(self, key)定义删除容器中指定元素的行为,相当于del self[key]

Sample 2:

编写一个可改变的自定义列表,并记录列表中每个元素被访问的次数。

class VariableList:
    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 = VariableList(1, 3, 5, 7, 9)
c2 = VariableList(1, 1, 2, 3, 5, 8, 11)
print(c1[1])  # 3
print(c2[2])  # 2
c2[2] = 10
print(c1[1] + c2[2])  # 13
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, 5: 0, 6: 0}
del c1[1]
print(c1.count)
# {0: 0, 1: 0, 2: 0, 3: 0}

9. 迭代器

  • 迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。
  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
  • 迭代器只能往前不会后退。
  • 字符串,列表或元组对象都可用于创建迭代器:

Sample 1:

string = 'endurance '
for c in string:
    print(c)

'''
e
n
d
u
r
a
n
c
e
'''

for c in iter(string):
    print(c)
'''
e
n
d
u
r
a
n
c
e
'''

Sample 2:

links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}
for each in links:
    print('%s -> %s' % (each, links[each]))

'''
B -> 百度
A -> 阿里
T -> 腾讯
'''

for each in iter(links):
    print('%s -> %s' % (each, links[each]))

'''
B -> 百度
A -> 阿里
T -> 腾讯
'''

迭代器有两个基本的方法:iter()next()

  • iter(object) 函数用来生成迭代器。
  • next(iterator[, default]) 返回迭代器的下一个项目。
  • iterator – 可迭代对象
  • default – 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 StopIteration 异常。
links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}
it = iter(links)
print(next(it))  # B
print(next(it))  # A
print(next(it))  # T
print(next(it))  # 重点:StopIteration


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

# B
# A
# T

把一个类作为一个迭代器使用需要在类中实现两个魔法方法 __iter__()__next__()

  • __iter__(self)定义当迭代容器中的元素的行为,返回一个特殊的迭代器对象, 这个迭代器对象实现了__next()__方法并通过 StopIteration 异常标识迭代的完成。
  • __next()__ 返回下一个迭代器对象。
  • StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next(``)__ 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
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 

10. 生成器

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


myG = myGen()
print(next(myG))  
# 生成器执行!
# 1

print(next(myG))  # 2
print(next(myG))  # StopIteration

myG = myGen()
for each in myG:
    print(each)

'''
生成器执行!
1
2
'''

生成器实现斐波那契数列。

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

11. 推导式

列表推导式

a = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]
print(a)
# [3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]

字典推导式

b = {i: i % 2 == 0 for i in range(10) if i % 3 == 0}
print(b)
# {0: True, 3: False, 6: True, 9: False}

集合推导式

c = {i for i in [1, 2, 3, 4, 5, 5, 6, 4, 3, 2, 1]}
print(c)
# {1, 2, 3, 4, 5, 6}

其它

d = 'i for i in "I Love Lsgogroup"'
print(d)
# i for i in "I Love Lsgogroup"

e = (i for i in range(10))
print(e)
# <generator object <genexpr> at 0x0000007A0B8D01B0>

print(next(e))  # 0
print(next(e))  # 1

for each in e:
    print(each, end=' ')

# 2 3 4 5 6 7 8 9

s = sum([i for i in range(101)])
print(s)  # 5050
s = sum((i for i in range(101)))
print(s)  # 5050

12. 魔法方法总结列表

魔法方法含义
基本的魔法方法
new(cls[, …])1. new 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 init 方法 3. new 决定是否要使用该 init 方法,因为 new 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 new 没有返回实例对象,则 init 不会被调用 4. new 主要是用于继承一个不可变的类型比如一个 tuple 或者 string
init(self[, …])构造器,当一个实例被创建的时候调用的初始化方法
del(self)析构器,当一个实例被销毁的时候调用的方法
call(self[, args…])允许一个类的实例像函数一样被调用:x(a, b) 调用 x.call(a, b)
len(self)定义当被 len() 调用时的行为
repr(self)定义当被 repr() 调用时的行为
str(self)定义当被 str() 调用时的行为
bytes(self)定义当被 bytes() 调用时的行为
hash(self)定义当被 hash() 调用时的行为
bool(self)定义当被 bool() 调用时的行为,应该返回 True 或 False
format(self, format_spec)定义当被 format() 调用时的行为
有关属性
getattr(self, name)定义当用户试图获取一个不存在的属性时的行为
getattribute(self, name)定义当该类的属性被访问时的行为
setattr(self, name, value)定义当一个属性被设置时的行为
delattr(self, name)定义当一个属性被删除时的行为
dir(self)定义当 dir() 被调用时的行为
get(self, instance, owner)定义当描述符的值被取得时的行为
set(self, instance, value)定义当描述符的值被改变时的行为
delete(self, instance)定义当描述符的值被删除时的行为
比较操作符
lt(self, other)定义小于号的行为:x < y 调用 x.lt(y)
le(self, other)定义小于等于号的行为:x <= y 调用 x.le(y)
eq(self, other)定义等于号的行为:x == y 调用 x.eq(y)
ne(self, other)定义不等号的行为:x != y 调用 x.ne(y)
gt(self, other)定义大于号的行为:x > y 调用 x.gt(y)
ge(self, other)定义大于等于号的行为:x >= y 调用 x.ge(y)
算数运算符
add(self, other)定义加法的行为:+
sub(self, other)定义减法的行为:-
mul(self, other)定义乘法的行为:*
truediv(self, other)定义真除法的行为:/
floordiv(self, other)定义整数除法的行为://
mod(self, other)定义取模算法的行为:%
divmod(self, other)定义当被 divmod() 调用时的行为
pow(self, other[, modulo])定义当被 power() 调用或 ** 运算时的行为
lshift(self, other)定义按位左移位的行为:<<
rshift(self, other)定义按位右移位的行为:>>
and(self, other)定义按位与操作的行为:&
xor(self, other)定义按位异或操作的行为:^
or(self, other)定义按位或操作的行为:|
反运算
radd(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rsub(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rmul(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rtruediv(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rfloordiv(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rmod(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rdivmod(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rpow(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rlshift(self, other)(与上方相同,当左操作数不支持相应的操作时被调用)
rrshift(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
类型转换
complex(self)定义当被 complex() 调用时的行为(需要返回恰当的值)
int(self)定义当被 int() 调用时的行为(需要返回恰当的值)
float(self)定义当被 float() 调用时的行为(需要返回恰当的值)
round(self[, n])定义当被 round() 调用时的行为(需要返回恰当的值)
index(self)1. 当对象是被应用在切片表达式中时,实现整形强制转换 2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 index 3. 如果 index 被定义,则 int 也需要被定义,且返回相同的值
上下文管理(with 语句)
enter(self)1. 定义当使用 with 语句时的初始化行为 2. enter 的返回值被 with 语句的目标或者 as 后的名字绑定
exit(self, exc_type, exc_value, traceback)1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么 2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作
容器类型
len(self)定义当被 len() 调用时的行为(返回容器中元素的个数)
getitem(self, key)定义获取容器中指定元素的行为,相当于 self[key]
setitem(self, key, value)定义设置容器中指定元素的行为,相当于 self[key] = value
delitem(self, key)定义删除容器中指定元素的行为,相当于 del self[key]
iter(self)定义当迭代容器中的元素的行为
reversed(self)定义当被 reversed() 调用时的行为
contains(self, item)定义当使用成员测试运算符(in 或 not in)时的行为

写在最后

小甲鱼视频还是要看的…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值