Python高级编程
程序员文章站
2022-06-23 11:37:38
自定义一个向量#from icecream import icimport mathclass Vector: #告诉解释器只有x,y两个变量,不会再有__dict__属性,节省内存 __slots__ = ('__x','__y') # https://www.cnblogs.com/rainfd/p/slots.html def __init__(self,x,y): self.__x= float(x) self.__...
自定义一个向量
#from icecream import ic
import math
class Vector:
#告诉解释器只有x,y两个变量,不会再有__dict__属性,节省内存
__slots__ = ('__x','__y')
# https://www.cnblogs.com/rainfd/p/slots.html
def __init__(self,x,y):
self.__x= float(x)
self.__y= float(y)
@property
# https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208
def x(self):
return self.__x
@property
def y(self):
return self.__y
# 对str提供支持
def __str__(self):
return str(tuple(self))
# 支持die dai
def __iter__(self):
return (i for i in (self.x,self.y))
# 对 repr提供支持
def __repr__(self):
"""
return Vector(x,y)
"""
return f'{type(self).__name__}({self.x},{self.y})'
# 对 hash 提供支持
# https://www.jianshu.com/p/4d3ef12eaf8e
# 如果 object 属于可哈希对象,hash() 函数将返回其哈希值;如果 object 不属于可哈希对象,hash() 函数则会抛出异常。哈希值是一个整数。
def __hash__(self):
return hash(self.x)^hash(self.y)
#对 abs 提供支持
def __abs__(self):
return math.hypot(self.x,self.y)
# hypot() 返回欧几里德范数 sqrt(x*x + y*y)
def __bool__(self):
return bool(abs(self))
v1 = Vector(3, 4)
#调用print其实是隐形点用了对象的str方法
print(v1)
运行结果:
(3.0, 4.0)
继承父类:
#继承Vector类
class Vector2d(Vector):
def __init__(self, x, y):
super().__init__(x, y)
self.__x = x
self.__y = y
v2 = Vector2d(5, 6)
print(v2)
运行结果:
(5.0, 6.0)
受保护的属性和私有属性¶
单下划线开头 _x
双下划线开头 __y
单下划线结尾 class_, 防止和内置类型冲突
from array import array
print(array('d', list(range(20))))
运行结果:
array('d', [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0])
N 维 Vector
import math
from array import array
import reprlib
from functools import reduce
class Vector:
# N 维 Vector
typecode = 'd' #浮点数8字节
def __init__(self, components):
self._components = array(self.typecode, components)
# components 组件 typecode 数字类型:整型,浮点型
#对str提供支持
def __str__(self):
return str(tuple(self))
def __iter__(self):
return (i for i in self._components)
#对 repr提供支持
def __repr__(self):
'''
return Vector([1.0, 2.0, 3.0...])
'''
components = reprlib.repr(self._components)
# 实例aRepr的实例方法。功能类似内建方法repr(),不过可以对返回的字符串大小进行限制。
components = components[components.find('['):-1]
# find 如果包含指定索引值,返回的是索引值在字符串中的起始位置。如果不包含索引值,返回-1
return f"{type(self).__name__}({components})"
# 对hash 提供支持
def __hash__(self):
hash_list = map(lambda x: hash(x),self._components)
return reduce(lambda a,b:a^b,hash_list,0)
# reduce 有三个参数, 第三个参数是初始值的意思,是可有可无的参数。
def __eq__(self,v):
if len(self) != len(v):
return False
for a,b in zip(self,v):
if a!=b:
return False
# return tuple(self) == tuple(v)
# return len(self) == len(self) and all(a ==b for a,b in zip(self,v))
#对abs提供支持
def __abs__(self):
return math.sqrt(sum(x*x for x in self._components))
# 切片 https://www.jianshu.com/p/c48e6e903c38
def __getitem__(self, index):
cls = type(self)
# type 与 isinstance 的区别
# https://blog.csdn.net/LoveL_T/article/details/83104234
if isinstance(index,slice):
# https://www.jianshu.com/p/c48e6e903c38
return cls(self._components[index])
elif isinstance(index,int):
return self._components[index]
else :raise TypeError(f"{cls.__name__} indices(指数) must be integers.")
# 运载符重载
#+
#https://www.cnblogs.com/lht-record/p/10306591.html
def __add__(self, v):
cls = type(self)
return cls([x +y for x, y in itertools.zip_longest(self,v,fillvalue=0)])
"""
def __add__(self, other):
pairs = itertools.zip_longest(self, other, fillvalue=0)
return Vector(a + b for a, b in pairs)
#pairs是一个生成器,生成(a, b)形式元组,a来自self,b来自other,0填充
"""
def __radd__(self,v):
return self + v
#__radd__是__add__的反向版本。
#__radd__直接委托__add__
# * scalar 乘以标量
def __mul__(self ,scalar):
cls = type(self)
return cls([x*scalar for x in self])
def __rmul__(self,scalar):
return self*scalar
#dot 点乘
def __matmul__(self, v):
cls = type(self)
return sum([a*b for a,b in itertools.zip_longest(self,v,fillvalue=1)])
def __rmatmul__(self,v):
return self@v
# 一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。
@staticmethod
def log():
print ("ok")
# staticmethod 返回函数的静态方法
"""
class C(object):
@staticmethod
def f():
print('runoob');
C.f(); # 静态方法无需实例化
cobj = C()
cobj.f() # 也可以实例化后调用
"""
多重继承与Mixin
Mixin 扩展类的功能
#Mixin 扩展类的功能
# https://blog.csdn.net/u012814856/article/details/81355935
import itertools
# class Plus:
# def plus(self, v):
# cls = type(self)
# return cls([x + y for x, y in itertools.zip_longest(self, v, fillvalue=0)])
# class Minus:
# def minus(self, v):
# cls = type(self)
# return cls([x - y for x, y in itertools.zip_longest(self, v, fillvalue=0)])
class CalculabilityMixin:
# +
def plus(self, v):
cls = type(self)
return cls([x + y for x, y in itertools.zip_longest(self, v, fillvalue=0)])
# -
def minus(self, v):
cls = type(self)
return cls([x - y for x, y in itertools.zip_longest(self, v, fillvalue=0)])
# @
def dot(self, v):
cls = type(self)
return sum([a * b for a, b in itertools.zip_longest(self, v, fillvalue=1)])
class LogMixin:
def __getitem__(self, index):
print(f"Getting value of index {index}.")
return super().__getitem__(index)
class Vector2d(LogMixin, CalculabilityMixin, Vector):
def __init__(self, *args):
components = list(args) if len(args) > 1 else args[0]
super().__init__(components)
self._x = components[0]
self._y = components[1]
v = Vector2d(1, 2)
print(v[0])
运行结果:
Getting value of index 0.
1.0
# 注意方法的搜索路径,不然容易产生错误
# 新类 宽度优先,旧类,深度优先
Vector2d.__mro__
运行结果:
(__main__.Vector2d, __main__.LogMixin, __main__.Vector, object)
v3 = Vector2d(1,2)
v4 = Vector2d(3,4)
print([3,4]+v3)
print(v3*10)
print(v3@[1,2])
print([1,2]@v3)
print(v3@v4)
运行结果:
Vector2d([4.0, 6.0])
Vector2d([10.0, 20.0])
5.0
5.0
11.0
1. 查官方文档 https://docs.python.org/3.6/¶
2. 直接Google 排名靠前的页面,尤其关注 * Google Python 风格指南 https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/contents/
def log():
print('ok')
class Vector2d(Vector):
def __init__(self, x, y):
super().__init__([x, y])
self._x = x
self._y = y
# https://blog.csdn.net/sinat_33718563/article/details/81298785
@classmethod
def build_from_other(cls, other_components):
if isinstance(other_components, list):
x, y = other_components
return cls(x, y)
v = Vector2d(1, 2)
v.log()
运行结果:
ok
本文地址:https://blog.csdn.net/weixin_40959890/article/details/110466968