我是靠谱客的博主 会撒娇龙猫,最近开发中收集的这篇文章主要介绍python学习笔记7-符合python风格的对象,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.例
from array import array
import math

class Vector2d:

typecode = 'd'#类属性
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def __iter__(self):# 将实例变为可迭代的对象 以实现拆包 调用生成器
return (i for i in (self.x, self.y)) # return (self.x, self.y)
def __repr(self):#使用{!r}获取两个值 *self拆分x,y
class_name = type(self).__name
return '{}({!r}, {!r})'.format(class_name, *self)
def __str__(self):#这是的Vector2d已经是可迭代对象了 所以可以直接得到一个元组
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 __bool__(self):
return bool(abs(self))

2.例 这是上例的一部分补充 也在类中定义
@classmethod
def frombytes(cls, octets):#不用传入self参数 相反需要通过cls来传入类本身
typecode = chr(octets[0])
memv = memoryview(octets[1:]).cast(typecode)
return cls(*memv)#拆包memoryview 得到构造方法需要的一堆参数

2.解释classmethod
要放在类中
定义操作类的方法 而不是操作实例的方法
第一个参数就是类本身 而不是实例

3.利用以上的装饰器来进行格式化显示
首先补充format用法
(1) print(’{name}在{option}’.format(name = ‘某人’, option = ‘写代码’)) 关键字
(2) print(‘name={} path={}’.format(‘张三’, ‘/’)) 位置
(3) print(’{1}在{0}’.format(‘写代码’, ‘某人’)
(4) print(’{num:.2f} is {num1:.5f}’.format(num = 3.1415, num1 = 3.14159265358979323846))

from datetime import datetime
now = datetime.now()
format(now, ‘%H:%M:%S’)

format(42, ‘b’)

4.我们想让编写的Vector2d也可以由format来格式化显示
比如 format(v1, ‘.2f’)
于是在前两条的Vector2d中加入
def format(self, fmt_spec = ’ '):
components = (format(c, fmt_spec) for c in self)#此时实现了类的可迭代 所以直接调用self 表示这个可迭代对象
return ‘({}, {})’.format(*component)#对于接受多个参数的函数或者定义式都可以用拆分的方式直接赋值 但是要注意一一对应

5.再为向量类 添加角度
def angle(self):
return math.atan2(self.y, self.x)
再次改进向量类的format
def format(self, fmt_spec = ’ '):
if fmt_spec.endswith(‘p’):#极坐标
fmt_spec = fmt_spec[:-1]
coords = (abs(self), self.angle())#调用其他函数
outer_fmt = ‘<{}, {}>’
else:
coords = self#当类是可迭代对象时 直接使用self表示这个可迭代对象
#可以赋值 可以进行迭代
outer_fmt = ‘({}, {})’
components = (format(c, fmt_spec) for c in coords)
return outer_fmt.format(*components)

6.可散列的Vector2d
现在的实例 v1.x = 7 可以直接给分量赋新值
我们想实现它的只读性 不可以随意修改
同时这个向量类的散列性 需要实现__hash__方法和__eq__方法
把x和y设为只读特性
class Vector2d:
typecode = ‘d’

def __init__(self):
self.__x = float(x)#双下划线使得属性标记为私有的
self.__y = float(y)
@property#把读值方法标记为特性
def x(self):
return self.__x
@property
def y(self):
return self.__y
def __iter__(self):
return (i for i in (self.x, self.y))

使得向量不可变 就可以求hash值
例:
def hash(self):
return hash(self.x) ^ hash(self.y)

7.Python的私有属性和受保护属性
因为可能会发生没有开放的实例属性在继承时再次创建 导致被覆盖的情况
self.__x 使得变为私有属性 会添加到 __dict__中
显示为_类名__x 这是名称改写
(1)另一种习惯是在属性前加 _ 解释器不会注意 但这是一种习惯 表示不要在类外部访问这种属性

8.使用__slots__类属性节省空间
python在各个实例中名为__dict__的字典里存储实例属性
使用__slots__类属性 告诉解释器 这个类中的所有实例属性都在这里
例如
class Vector2d:
slots = (’__x’, ‘__y’)
typecode = ‘d’
注意事项:子类也要定义__slots__属性 不会继承
实例只能拥有__slots__中列出的属性
__slots__不加入’weakref’就不能作为弱引用的目标

9.python中类属性可以为实例属性提供默认值
比如实例属性没有 但是有同名类属性 则会取类属性的值
这时给不存在的实例属性赋值 会新建实例属性 并不再使用类属性

最后

以上就是会撒娇龙猫为你收集整理的python学习笔记7-符合python风格的对象的全部内容,希望文章能够帮你解决python学习笔记7-符合python风格的对象所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部