企业网站优化三层含义,qq网页版 登陆,标准化建设考评网站,绵阳 网站开发一、核心要义
以第九章定义的二维向量为基础#xff0c;定义表示多为向量的Vector类。该类将支持如下功能#xff1a;
1. 基本的序列协议
2. 适当的切片支持#xff0c;且返回的是新Vector实例
3.综合各个元素的值计算散列值
4.格式化展示
二、代码示例
1、前情提要 …一、核心要义
以第九章定义的二维向量为基础定义表示多为向量的Vector类。该类将支持如下功能
1. 基本的序列协议
2. 适当的切片支持且返回的是新Vector实例
3.综合各个元素的值计算散列值
4.格式化展示
二、代码示例
1、前情提要
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 13:56
# Author : Maple
# File : 00-相关背景知识.py
# Software: PyCharmclass MySeq:def __getitem__(self, index):return indexif __name__ __main__:# mylist [1,2,3,4,5,6]# print(mylist[1:5:2]) # [2, 4]# 1. 自定义序列的getitem方法中的index测试s MySeq()## 1-1 单个索引,index返回的是整数print(s[1])## 1-2 1:4 返回的是slice(1, 4, None),其中1是序列的起始位置,4是结束位置,而且是左闭右开,即[1,4)print(s[1:4]) # slice(1, 4, None)## 1-3 1:4:2 返回的是slice(1, 4, 2),其中1是序列的起始位置,4是结束位置,2代表步长print(s[1:4:2]) # slice(1, 4, 2)## 1-4 复合切片1print(s[1:4:2,9]) # (slice(1, 4, 2), 9)#1-5 复合切片2print(s[1:4:2,7:9]) #(slice(1, 4, 2), slice(7, 9, None))# 2.slice测试slice是Python内置的类型##2-1 slice有一个indices方法, 以及start,step和stop三个数据属性print(dir(slice)) # [..indices, start, step, stop]]##2-2 而indices方法主要是用于优雅地处理缺失索引和负索引,以及长度超过目标序列的切片### 2-2-1 对一个长度为5的序列,进行切片,其中起始位置缺失,结束位置为10(很显然已经超过了序列长度),步长为2### indices方法会帮忙将切片调整为 :(0, 5, 2)print(slice(None,10,2).indices(5))### 2-2-2 对一个长度为5的序列,进行切片,其中起始位置为-3,结束位置未知,步长未知### indices方法会帮忙将切片调整为 :(2, 5, 1)print(slice(-3,None,None).indices(5))# 3. 格式化测试name mapleage 18print({name!r} and {age!r}.format(name name,age age)) # maple and 18print({!r} and {!r}.format(name,age)) # maple and 18,不能使用关键字参数传递print({name!r} and {!r}.format(age,namename)) # maple and 18,positional argument要放在前面2、Vector类的改造
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 14:19
# Author : Maple
# File : 01-Vector类的改造.py
# Software: PyCharm相对于第9章的Vector类-构造方法是传入形如(1,2)这样的二元元组本章的Vector类
-(1)首先是可以接收任意多个参数
-(2)构造方法传入的是可迭代的对象import math
import reprlib
from array import arrayclass Vector:typecode ddef __init__(self,components):self._components array(self.typecode,components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __eq__(self, other):return tuple(self) tuple(other)def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls,octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)if __name__ __main__:v Vector([1,2,3,4])print(*******1. repr测试*****************)# 1. repr测试 如果没有定义str方法,print(v)会调用__repr__方法print(v) # Vector([1.0, 2.0, 3.0, 4.0])# 2.str测试print(*******2. str测试*****************)print(v) # (1.0, 2.0, 3.0, 4.0)# 3.相等性测试print(*******3.相等性测试*****************)v2 Vector([1,2,3,4])print(v is v2) # False,不同的对象print(v v2) # False,值相等# 4.迭代测试print(*******4.迭代测试****************)for i in v:1.02.03.04.0
print(i)# 5.模长(abs)测试print(*******5.模长(abs)测试****************)print(abs(v)) # 5.477225575051661# 6. bytes测试print(*******6. bytes测试****************)print(bytes(v)) # bd\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x10#7. frombytes测试print(*******7. frombytes测试****************)v_byte bytes(v)v_clone Vector.frombytes(v_byte)print(v v_clone)# 8. 切片测试: 未实现getitem方法,无法使用切片print(v[1:3]) # TypeError: Vector object is not subscriptable
3、Vector类切片功能实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 14:57
# Author : Maple
# File : 02-Vector类切片功能实现.py
# Software: PyCharm#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 14:19
# Author : Maple
# File : 01-Vector类的改造.py
# Software: PyCharm相对于第9章的Vector类-构造方法是传入形如(1,2)这样的二元元组本章的Vector类
-(1)首先是可以接收任意多个参数
-(2)构造方法传入的是可迭代的对象import math
import numbers
import reprlib
from array import arrayclass Vector:切片返回数组typecode ddef __init__(self,components):self._components array(self.typecode,components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __eq__(self, other):return tuple(self) tuple(other)def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls,octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)def __len__(self):return len(self._components)def __getitem__(self, index):# index是一个slice类型数据,返回数组return self._components[index]class Vector2:切片仍然返回Vector类型数据typecode ddef __init__(self,components):self._components array(self.typecode,components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __eq__(self, other):return tuple(self) tuple(other)def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls,octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)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 {cls.__name__} indices must be integersreturn TypeError(msg.format(cls cls))if __name__ __main__:v Vector([1,2,3,4,5])# 1. 切片测试返回的是数组print(v[1]) # 2.0print(v[1:3]) # array(d, [2.0, 3.0])print(v[1:5:2]) # array(d, [2.0, 4.0])# slice(1,5,2)print(v[-4:10:2]) # array(d, [2.0, 4.0])# 2. 切片测试返回的是Vector类型数据v2 Vector2([1, 2, 3, 4, 5])print(v2[1]) # 2.0print(v2[1:3]) # (2.0, 3.0)print(v2[1:5:2]) # (2.0, 4.0)print(v2[1.0]) # Vector2 indices must be integers
4、Vector类动态存取属性
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 15:10
# Author : Maple
# File : 03-Vector类动态存取属性.py
# Software: PyCharm
import numbers
import reprlib
from array import arrayclass Vector:实现能够通过单个变量访问前几个分量,比如 v.x,v.y等实现方式: getattr方法typecode dshortcut_names xyztdef __init__(self,components):self._components array(self.typecode,components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __eq__(self, other):return tuple(self) tuple(other)def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls,octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)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 {cls.__name__} indices must be integersreturn TypeError(msg.format(cls cls))def __getattr__(self, item):# 只有当v.x实例不存在x属性时,才会调用getattrcls type(self)if len(item) 1:position cls.shortcut_names.find(item)if 0 position len(self._components):return self._components[position]msg {.__name__!r} object has not attribute {!r}raise AttributeError(msg.format(cls,item))class Vector2:实现能够通过单个变量访问前几个分量,比如 v.x,v.y等实现方式: getattr方法typecode dshortcut_names xyztdef __init__(self, components):self._components array(self.typecode, components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __eq__(self, other):return tuple(self) tuple(other)def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls, octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)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 {cls.__name__} indices must be integersreturn TypeError(msg.format(clscls))def __getattr__(self, item):# 只有当v.x实例不存在x属性时,才会调用getattrcls type(self)if len(item) 1:position cls.shortcut_names.find(item)if 0 position len(self._components):return self._components[position]msg {.__name__!r} object has not attribute {!r}raise AttributeError(msg.format(cls, item))def __setattr__(self, name, value):cls type(self)if len(name) 1:# 限制修改xyzt单字母属性值if name in cls.shortcut_names:error readonly attribute {attr_name!r}elif name.islower():# 限制修改单字母(a-z)的属性值error cant set attributes a to z in {cls_name}!relse:error if error:msg error.format(cls_namecls, attr_namename)raise AttributeError(msg)# 允许修改名字为其它值的属性super().__setattr__(name, value)if __name__ __main__:# 1.未设置setattr方法时的测试v Vector([1,2,3,4,5])print(v.x) # 1.0# print(v.q) # Vector object has not attribute qv.x 10# 当设置了v.x 10之后,相当于给v实例新增了属性x(self.x x),之后再访问v.x,不会走getattr方法,而是直接访问实例v的属性x的值print(v.x) # 10# 但是v的第一个分量值仍然为1.0,并没有发生变化(也正常,毕竟getattr方法也没有修改_components的值)# 但是上述两条结果时矛盾的v.x(本意是对应实例v的第一个分量)的值发生了变化,但是通过直接访问v-的第一个分量值却又没有发生变化# 为了避免上述矛盾可以通过setattr方法限制修改单字母属性的值print(v) # (1.0, 2.0, 3.0, 4.0, 5.0)# 2. 设置setattr方法时的测试print(*********2. 设置setattr方法时的测试************)v2 Vector2([1, 2, 3, 4, 5])print(v2.x)## 2-1 尝试修改v2.x的值#v2.x 10 # AttributeError: readonly attribute x## 2-2 尝试修改[a-z]之间某个单值属性的值#v2.a 100 # AttributeError: cant set attributes a to z in class __main__.Vector2!r## 2-3 尝试修改名字为其它值的属性v2.name Maple# 修改成功print(v2.name) # Maple# 3.散列测试v3 Vector2([1, 2, 3, 4, 5])v4 Vector2([1, 2, 3, 4, 5])# 未实现hash方法不能散列化set([v3,v4]) #TypeError: unhashable type: Vector2
5、Vector类实现散列化
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 17:26
# Author : Maple
# File : 04-Vector类实现散列化.py
# Software: PyCharmimport functools
import numbers
import operator
import reprlib
from array import array
实现__eq__(已实现,为提升效率改写以下)和__hash__
class Vector:typecode dshortcut_names xyztdef __init__(self, components):self._components array(self.typecode, components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls, octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)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 {cls.__name__} indices must be integersreturn TypeError(msg.format(clscls))def __getattr__(self, item):# 只有当v.x实例不存在x属性时,才会调用getattrcls type(self)if len(item) 1:position cls.shortcut_names.find(item)if 0 position len(self._components):return self._components[position]msg {.__name__!r} object has not attribute {!r}raise AttributeError(msg.format(cls, item))def __setattr__(self, name, value):cls type(self)if len(name) 1:# 限制修改xyzt单字母属性值if name in cls.shortcut_names:error readonly attribute {attr_name!r}elif name.islower():# 限制修改单字母(a-z)的属性值error cant set attributes a to z in {cls_name}!relse:error if error:msg error.format(cls_namecls, attr_namename)raise AttributeError(msg)# 允许修改名字为其它值的属性super().__setattr__(name, value)def __eq__(self, other):# 如果分量太多,下面这种方式效率太低# return tuple(self) tuple(other)if len(self) ! len(other):return Falsefor x, y in zip(self, other):if x ! y:return Falsereturn Truedef __hash__(self):# 生成一个迭代器hashes (hash(x) for x in self._components)return functools.reduce(operator.xor, hashes, 0)# 等价于下面的写法# return functools.reduce(lambda x,y : x *y ,hashes,0)if __name__ __main__:v1 Vector([1, 2, 3, 4, 5])v2 Vector([1, 2, 3, 4, 5])print(set([v1, v2])) # {Vector([1.0, 2.0, 3.0, 4.0, 5.0])}
6、Vector类格式化
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2024/2/17 17:38
# Author : Maple
# File : 05-Vector类格式化.py
# Software: PyCharmimport functools
import itertools
import math
import numbers
import operator
import reprlib
from array import arrayclass Vector:typecode dshortcut_names xyztdef __init__(self, components):self._components array(self.typecode, components)def __repr__(self):# 返回的components是str类型components reprlib.repr(self._components)components components[components.find([):-1]return Vector({}).format(components)def __str__(self):return str(tuple(self))def __iter__(self):return iter(self._components)def __bytes__(self):return (bytes([ord(self.typecode)]) bytes(self._components))def __bool__(self):return bool(abs(self))def __abs__(self):return math.sqrt(sum(x * x for x in self._components))classmethoddef frombytes(cls, octets):typecode chr(octets[0])memv memoryview(octets[1:]).cast(typecode)return cls(memv)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 {cls.__name__} indices must be integersreturn TypeError(msg.format(clscls))def __getattr__(self, item):# 只有当v.x实例不存在x属性时,才会调用getattrcls type(self)if len(item) 1:position cls.shortcut_names.find(item)if 0 position len(self._components):return self._components[position]msg {.__name__!r} object has not attribute {!r}raise AttributeError(msg.format(cls, item))def __setattr__(self, name, value):cls type(self)if len(name) 1:# 限制修改xyzt单字母属性值if name in cls.shortcut_names:error readonly attribute {attr_name!r}elif name.islower():# 限制修改单字母(a-z)的属性值error cant set attributes a to z in {cls_name}!relse:error if error:msg error.format(cls_namecls, attr_namename)raise AttributeError(msg)# 允许修改名字为其它值的属性super().__setattr__(name, value)def __eq__(self, other):# 如果分量太多,下面这种方式效率太低# return tuple(self) tuple(other)if len(self) ! len(other):return Falsefor x, y in zip(self, other):if x ! y:return Falsereturn Truedef __hash__(self):# 生成一个迭代器hashes (hash(x) for x in self._components)return functools.reduce(operator.xor, hashes, 0)# 等价于下面的写法# return functools.reduce(lambda x,y : x *y ,hashes,0)# 计算n维球体的某个角坐标def angle(self,n):r math.sqrt(sum(x * x for x in self[n:]))a math.atan2(r,self[n-1])if (n len(self) - 1) and (self[-1] 0):return math.pi * 2 - 1else:return adef angles(self):return (self.angle(n) for n in range(1,len(self)))def __format__(self, fmt_spec):if fmt_spec.endswith(h): # 超球面体fmt_spec fmt_spec[:-1]coords itertools.chain([abs(self)],self.angles())outer_format {}else:coords selfouter_format ({})components (format(c,fmt_spec) for c in coords)return outer_format.format(, .join(components))if __name__ __main__:# 格式化输出测试v1 Vector([1, 2, 3, 4, 5])# 球面极坐标输出print(format(v1,.2fh)) # 7.42, 1.44, 1.30, 1.13, 0.90# 其它正常格式输出print(format(v1,.2f)) # (1.00, 2.00, 3.00, 4.00, 5.00)print(format(v1,.2e)) #(1.00e00, 2.00e00, 3.00e00, 4.00e00, 5.00e00)