魔术方法

一、什么是魔术方法?

魔术方法特殊方法的昵称。特殊方法也叫双下方法。类似这样:__getitem__

二、使用特殊方法示例

from math import hypot

# 二维向量类
# 自定义特殊方法
class Vector(object):
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Vector(%r,%r)' % (self.x, self.y)

    def __abs__(self):
        return hypot(self.x, self.y)

    def __mul__(self, other):
        return Vector(self.x * other, self.y * other)

    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)

a = Vector(3, 4)
b = Vector(1, 2)
print(abs(a), a * 3)
print(a + b)

三、特殊方法汇总

1、非数学运算

 ①、 字符串表示
        __repr__
        __str__


②、 集合、序列相关
        __len__
        __getitem__
        __setitem__
        __delitem__
        __contains__


③、迭代相关
        __iter__
        __next__


④、可调用
        __call__


⑤、with上下文管理器
        __enter__
        __exit__


⑥、数值转换
        __abs__
        __bool__
        __int__
        __float__
        __hash__
        __index__


⑦、元类相关
        __new__
        __init__


⑧、属性相关
        __getattr__、 __setattr__
        __getattribute__、setattribute__
        __dir__


⑨、属性描述符
        __get__、__set__、 __delete__


⑩、协程
        __await__、__aiter__、__anext__、__aenter__、__aexit__

 2、数学运算

① 一元运算符
        __neg__(-)、__pos__(+)、__abs__


 ②二元运算符
        __lt__(<)、 __le__ <= 、 __eq__ == 、 __ne__ != 、 __gt__ > 、 __ge__ >=


 ③算术运算符
        __add__ + 、 __sub__ - 、 __mul__ * 、 __truediv__ / 、 __floordiv__ // 、 __mod__ % 、 __divmod__ divmod() 、 __pow__ ** 或 pow() 、 __round__ round()


④反向算术运算符
        __radd__ 、 __rsub__ 、 __rmul__ 、 __rtruediv__ 、 __rfloordiv__ 、 __rmod__ 、__rdivmod__ 、 __rpow__


⑤增量赋值算术运算符
        __iadd__ 、 __isub__ 、 __imul__ 、 __itruediv__ 、 __ifloordiv__ 、 __imod__ 、__ipow__


⑥位运算符
        __invert__ ~ 、 __lshift__ << 、 __rshift__ >> 、 __and__ & 、 __or__ | 、 __xor__ ^


⑦反向位运算符
        __rlshift__ 、 __rrshift__ 、 __rand__ 、 __rxor__ 、 __ror__


⑧增量赋值位运算符
        __ilshift__ 、 __irshift__ 、 __iand__ 、 __ixor__ 、 __ior__

⑨一元运算符
    __neg__(-)、__pos__(+)、__abs__


⑩二元运算符
    __lt__(<)、 __le__ <= 、 __eq__ == 、 __ne__ != 、 __gt__ > 、 __ge__ >=


11算术运算符
    __add__ + 、 __sub__ - 、 __mul__ * 、 __truediv__ / 、 __floordiv__ // 、 __mod__ % 、 __divmod__ divmod() 、 __pow__ ** 或 pow() 、 __round__ round()


12反向算术运算符
    __radd__ 、 __rsub__ 、 __rmul__ 、 __rtruediv__ 、 __rfloordiv__ 、 __rmod__ 、__rdivmod__ 、 __rpow__


13增量赋值算术运算符
    __iadd__ 、 __isub__ 、 __imul__ 、 __itruediv__ 、 __ifloordiv__ 、 __imod__ 、__ipow__


14位运算符
    __invert__ ~ 、 __lshift__ << 、 __rshift__ >> 、 __and__ & 、 __or__ | 、 __xor__ ^


15反向位运算符
    __rlshift__ 、 __rrshift__ 、 __rand__ 、 __rxor__ 、 __ror__


16增量赋值位运算符
    __ilshift__ 、 __irshift__ 、 __iand__ 、 __ixor__ 、 __ior__

 应用实例:



import math
from array import array


class Vector2d(object):
    typecode = 'd'

    def __init__(self, x, y):
        self.__x = float(x)  # 只有向量不可变,才能实现__hash__方法
        self.__y = float(y)

    @property
    def x(self):  # 可通过这两个方法读取公开特性,而不必访问私有属性
        return self.__x

    @property
    def y(self):
        return self.__y

    def __repr__(self):
        class_name = type(self).__name__
        return '{}({!r},{!r})'.format(class_name, *self)

    def __iter__(self):
        return (i for i in (self.x, self.y))

    def __str__(self):
        return str(tuple(self))

    def __bytes__(self):
        return (bytes([ord(self.typecode)]) + bytes(array(self.typecode, self)))

    def __eq__(self, other):
        return tuple(self) == tuple(other)

    def __abs__(self):
        return math.hypot(self.x, self.y)

    def __bool__(self):
        return bool(abs(self))

    # def __format__(self, format_spec=''):
    #     componets = (format(c, format_spec) for c in self)
    #     return '({},{})'.format(*componets)
    def angle(self):
        return math.atan2(self.x, self.y)

    # 增强版,计算极坐标
    def __format__(self, format_spec=''):
        if format_spec.endswith('p'):
            format_spec = format_spec[:-1]
            coords = (abs(self), self.angle())
            outer_fmt = '<{},{}>'
        else:
            coords = self
            outer_fmt = '({},{})'

        components = (format(c, format_spec) for c in coords)
        return outer_fmt.format(*components)

    def __hash__(self):
        return hash(self.x) ^ hash(self.y)

    def __complex__(self):  # 实现虚数
        return complex(self.x, self.y)


v1 = Vector2d(3, 4)
v2 = Vector2d(3.1, 4.2)
# print(format(v1))
# print(format(v1, '.2e'))
# print(format(v1, '.2f'))
# print(format(Vector2d(1, 1), 'p'))
# print(hash(v1))  # 不可hash的,想要变成可散列的,要把x和y变成不可改变的
# print(hash(v1))
# print(hash(v2))
# print(set([v1,v2]))
print(complex(v1))  
print(complex(v2))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值