Python23.5_运算符重载、序列与切片

运算符重载

from math import hypot,sqrt
class Vector2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        """
        加法重载
        :param other:
        :return:
        """
        x = self.x + other.x
        y = self.y + other.y
        return Vector2D(x, y)

    def __str__(self):
        return "Vector2D(x = {},y = {})".format(self.x, self.y)

    def __sub__(self, other):
        """
        减法重载
        :param other:
        :return:
        """
        x = self.x - other.x
        y = self.y - other.y
        return Vector2D(x, y)

    def __mul__(self, other):
        """
        乘法重载
        :param other:
        :return:
        """
        x = self.x * other.x
        y = self.y * other.y
        return Vector2D(x, y)
    def __truediv__(self, other):
        """
        除法重载
        :param other:
        :return:
        """
        x = self.x / other.x
        y = self.y / other.y
        return Vector2D(x, y)
    def __divmod__(self, other):
        """
        返回商和余数的元组
        :param other:
        :return:
        """
        pass
    def __eq__(self, other):
        """
        判断两个对象是否相等
        :param other:
        :return:
        """
        pass
    def __abs__(self):
        """
        绝对值函数重载
        :return:
        """
        return sqrt(self.x ** 2 + self.y)
        #或者return hypot(self.x, self.y) #效率更高,因为底层是拿C写的

    def __len__(self):
        """
        重写len方法,返回值必须为整数
        :return:
        """
        pass

    def __iadd__(self, other):
        """
        对+=重载,就地操作:对本身进行操作,如果不对此方法进行重写,+=时就会自动调用重写了的add方法
        :param other:
        :return:
        """
        print("__iadd__")
        return self.__add__(other)

v1 = Vector2D(1, 2)
v2 = Vector2D(4, 4)
print(v1 + v2)
print(v1 - v2)
print(v1 * v2)
print(v1 / v2)
v1 += v2
print(v1)
print(abs(v1))

ps:对方法重写后,可以返回NotImplemented,告诉编译器没有实现这个方法(尽管这个方法实际上实现了)

__add__、__radd__、__iadd__的区别

对于a+b:

  1. 如果a有__add__方法,并且返回值不是NotImplemented,则调用a的add方法
  2. 如果a没有add方法,或者返回了NotImplemented,检查b有没有radd方法,如果有,则执行,如果没有,则报错
  3. i表示就地操作,即+=,-=之类的
class A:
    def __add__(self, other):
        print("A__add")
        return NotImplemented
    def __radd__(self, other):
        print("A__radd")

A() + B()   #调用A的add方法
B() + A()   #想调用B的add方法,但是没有被重写,于是调用A的radd方法

__repr__、__str__方法的区别

  1. __str__不存在的时候,会尝试调用repr
  2. __str__是为了让人读,而repr是为了让机器读
  3. __str__是由print和str()函数调用,而__repr__是由repr()函数调用
class Student:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        """
        如果没有实现__str__方法,则会调用此方法
        :return:
        """
        return "Student:%s"%self.name

s = Student("lisi")
print(s)

序列

只要实现了__getitem____len__方法,就会被认定是序列,就支持用for循环遍历,支持切片操作,等。

import collections
import random

#如果一个类里面只有属性,没有方法,则可以这么定义
Card = collections.namedtuple("Card", ["rank","suit"])

class Puke:
    ranks = [str(n) for n in list(range(2,11)) + list("JQKA")]    #后面的range和list连接起来了
    suits = "黑桃 方块 梅花 红心".split()

    def __init__(self):
        self.cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]
    def __len__(self):
        return len(self.cards)

    def __getitem__(self, item):
        return self.cards[item]

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

pk = Puke()
# print(pk.cards)
# print(len(pk.cards))
# for card in pk:
#     print(card)
# pk[1:3] = Card(rank="A",suit="biubiubiu~"), Card(rank="A",suit="biubiubiu~")
# print(pk.cards)

#洗牌
random.shuffle(pk)
print(pk.cards)
print("\n发牌".center(50, "*"))
print(pk[:13])
print(pk[13:26])
print(pk[26:39])
print(pk[39:])

切片(slice(start, end, step))

slice:是用于规定序列的选取规则

step = slice(0,5,2)
component = [i for i in range(10)]
print(component[step])
```**

猜你喜欢

转载自blog.csdn.net/qq_34873298/article/details/92379659
今日推荐