美文网首页
Python31_运算符重载、序列与切片

Python31_运算符重载、序列与切片

作者: jxvl假装 | 来源:发表于2019-09-27 12:31 被阅读0次

运算符重载

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])

相关文章

  • Python31_运算符重载、序列与切片

    运算符重载 ps:对方法重写后,可以返回NotImplemented,告诉编译器没有实现这个方法(尽管这个方法实际...

  • 17-容器类型公共方法

    python内置函数 切片 注意:字典是不能进行切片。 运算符 成员运算符成员运算符用于判断成语是否在序列中,in...

  • 运算符重载及其他约定

    7.1 重载算术运算符 重载二元算术运算符 重载复合赋值运算符 重载一元运算符 重载比较运算符 等号运算符:‘eq...

  • C++ 部分运算符重载

    可重载的运算符 不可重载的运算符和符号 重载运算符为类的成员函数 重载运算符为友元函数 重载赋值运算符 重载流插入...

  • 如何为类和结构体自定义运算符实现

    运算符重载 类和结构体可以为现有的运算符提供自定义的实现,称为运算符重载。 一元运算符重载 类与结构体也能提供标准...

  • 2019-07-11 运算符的重载

    运算符的重载 重载运算符 (“::”,“.*”,“.”,“?:”)不能被重载。 重载运算符时,不能改变其本质,如不...

  • 《C++Primer》第十九章

    第十九章 特殊工具与技术 控制内存分配 1. 重载new和delete 重载这两个运算符与重载其他运算符的过程大不...

  • 为类和结构体自定义运算符实现

    运算符重载 类和结构体可以为现有的运算符提供自定义的视线,称为运算符重载 一元运算符重载 类与结构体也能提供标准一...

  • 运算符重载

    一.+号运算符重载 二.<<号运算符重载 三.指针运算符重载(智能指针)

  • C++运算符重载-下篇 (Boolan)

    C++运算符重载-下篇 (Boolan) 本章内容:1. 运算符重载的概述2. 重载算术运算符3. 重载按位运算符...

网友评论

      本文标题:Python31_运算符重载、序列与切片

      本文链接:https://www.haomeiwen.com/subject/xehuuctx.html