专栏首页sktjpython 类切片的实现

python 类切片的实现

A multi-dimensional Vector class, take 3

A Vector is built from an iterable of numbers::

>>> Vector([3.1, 4.2])
Vector([3.1, 4.2])
>>> Vector((3, 4, 5))
Vector([3.0, 4.0, 5.0])
>>> Vector(range(10))
Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...])

Tests with 2-dimensions (same results as vector2d_v1.py)::

>>> v1 = Vector([3, 4])
>>> x, y = v1
>>> x, y
(3.0, 4.0)
>>> v1
Vector([3.0, 4.0])
>>> v1_clone = eval(repr(v1))
>>> v1 == v1_clone
True
>>> print(v1)
(3.0, 4.0)
>>> octets = bytes(v1)
>>> octets
b'd\\x00\\x00\\x00\\x00\\x00\\x00\\x08@\\x00\\x00\\x00\\x00\\x00\\x00\\x10@'
>>> abs(v1)
5.0
>>> bool(v1), bool(Vector([0, 0]))
(True, False)

Test of .frombytes() class method:

>>> v1_clone = Vector.frombytes(bytes(v1))
>>> v1_clone
Vector([3.0, 4.0])
>>> v1 == v1_clone
True

Tests with 3-dimensions::

>>> v1 = Vector([3, 4, 5])
>>> x, y, z = v1
>>> x, y, z
(3.0, 4.0, 5.0)
>>> v1
Vector([3.0, 4.0, 5.0])
>>> v1_clone = eval(repr(v1))
>>> v1 == v1_clone
True
>>> print(v1)
(3.0, 4.0, 5.0)
>>> abs(v1)  # doctest:+ELLIPSIS
7.071067811...
>>> bool(v1), bool(Vector([0, 0, 0]))
(True, False)

Tests with many dimensions::

>>> v7 = Vector(range(7))
>>> v7
Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...])
>>> abs(v7)  # doctest:+ELLIPSIS
9.53939201...

Test of .__bytes__ and .frombytes() methods::

>>> v1 = Vector([3, 4, 5])
>>> v1_clone = Vector.frombytes(bytes(v1))
>>> v1_clone
Vector([3.0, 4.0, 5.0])
>>> v1 == v1_clone
True

Tests of sequence behavior::

>>> v1 = Vector([3, 4, 5])
>>> len(v1)
3
>>> v1[0], v1[len(v1)-1], v1[-1]
(3.0, 5.0, 5.0)

Test of slicing::

>>> v7 = Vector(range(7))
>>> v7[-1]
6.0
>>> v7[1:4]
Vector([1.0, 2.0, 3.0])
>>> v7[-1:]
Vector([6.0])
>>> v7[1,2]
Traceback (most recent call last):
  ...
TypeError: Vector indices must be integers

Tests of dynamic attribute access::

>>> v7 = Vector(range(10))
>>> v7.x
0.0
>>> v7.y, v7.z, v7.t
(1.0, 2.0, 3.0)

Dynamic attribute lookup failures::

>>> v7.k
Traceback (most recent call last):
  ...
AttributeError: 'Vector' object has no attribute 'k'
>>> v3 = Vector(range(3))
>>> v3.t
Traceback (most recent call last):
  ...
AttributeError: 'Vector' object has no attribute 't'
>>> v3.spam
Traceback (most recent call last):
  ...
AttributeError: 'Vector' object has no attribute 'spam'

Tests of preventing attributes from 'a' to 'z'::

>>> v1.x = 7
Traceback (most recent call last):
  ...
AttributeError: readonly attribute 'x'
>>> v1.w = 7
Traceback (most recent call last):
  ...
AttributeError: can't set attributes 'a' to 'z' in 'Vector'

Other attributes can be set::

>>> v1.X = 'albatross'
>>> v1.X
'albatross'
>>> v1.ni = 'Ni!'
>>> v1.ni
'Ni!'

"""

from array import array import reprlib import math import numbers

class Vector: typecode = 'd'

def __init__(self, components):
    self._components = array(self.typecode, components)

def __iter__(self):
    return iter(self._components)

def __repr__(self):
    components = reprlib.repr(self._components)
    components = components[components.find('['):-1]
    return 'Vector({})'.format(components)

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

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

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

def __abs__(self):
    return math.sqrt(sum(x * x for x in self))

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

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

def __getitem__(self, index):
    cls = type(self)
    if isinstance(index, slice):
        return cls(self._components[index])
    elif isinstance(index, numbers.Integral):
        return self._components[index]
    else:
        msg = '{.__name__} indices must be integers'
        raise TypeError(msg.format(cls))

BEGIN VECTOR_V3_GETATTR

shortcut_names = 'xyzt'

def __getattr__(self, name):
    cls = type(self)  # <1>
    if len(name) == 1:  # <2>
        pos = cls.shortcut_names.find(name)  # <3>
        if 0 <= pos < len(self._components):  # <4>
            return self._components[pos]
    msg = '{.__name__!r} object has no attribute {!r}'  # <5>
    raise AttributeError(msg.format(cls, name))

END VECTOR_V3_GETATTR

BEGIN VECTOR_V3_SETATTR

def __setattr__(self, name, value):
    cls = type(self)
    if len(name) == 1:  # <1>
        if name in cls.shortcut_names:  # <2>
            error = 'readonly attribute {attr_name!r}'
        elif name.islower():  # <3>
            error = "can't set attributes 'a' to 'z' in {cls_name!r}"
        else:
            error = ''  # <4>
        if error:  # <5>
            msg = error.format(cls_name=cls.__name__, attr_name=name)
            raise AttributeError(msg)
    super().__setattr__(name, value)  # <6>

END VECTOR_V3_SETATTR

@classmethod
def frombytes(cls, octets):
    typecode = chr(octets[0])
    memv = memoryview(octets[1:]).cast(typecode)
    return cls(memv)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • IOS UIResponder 触碰拖动图像

    override func touchesMoved(_ touches:Set<UITouch>, with event:UIEvent?) { //需要先...

    用户5760343
  • python 通过字符串方式调用方法operator.methodcaller

    class Point: def init(self, x, y): self.x = x self.y = y

    用户5760343
  • python 用装饰器给函数增加参数

    用户5760343
  • go语言中json转成map结构

    package main import ( "encoding/json" "fmt" ) //把请求包定义成一个结构体 type Reques...

    李海彬
  • Go语言中json转成map结构

    package main import ( "encoding/json" "fmt" ) //把请求包定义成一个结构体 type Reques...

    李海彬
  • go语言中json转成map结构

    package main import ( "encoding/json" "fmt" ) //把请求包定义成一个结构体 type Reques...

    李海彬
  • go语言中json转成map结构

    package main import ( "encoding/json" "fmt" ) //把请求包定义成一个结构体 type Reques...

    李海彬
  • 基础:为什么计算机只认识0和1?

    端午节放假休息,我正在家里面吹着空调,吃着西瓜,看着《这就是街舞》,女朋友在一旁看某游戏主播的直播。我隐约中听到她手机中传来主播的一句话:“朋友们,听懂我的意思...

    Java3y
  • 为什么计算机只认识0和1?

    计算机(computer)俗称电脑,是现代一种用于高速计算的电子计算机器,可以进行数值计算,又可以进行逻辑计算,还具有存储记忆功能。是能够按照程序运行,自动、高...

    JAVA葵花宝典
  • 宝利通Polycom CX600版本升级

    最近项目需要,把宝利通Polycom CX600版本从4.0.7577.4455升级到最新版本4.0.7577.4512。

    杨强生

扫码关注云+社区

领取腾讯云代金券