第9章 符合Python风格的对象
#《流畅的Python》读书笔记
# 第9章 符合Python风格的对象
# 本章包含以下话题:
# 支持用于生成对象其他表示形式的内置函数(如repr()、bytes(),等等)
# 使用一个类方法实现备选构造方法
# 扩展内置的 format() 函数和 str.format() 方法使用的格式微语言
# 实现只读属性
# 把对象变为可散列的,以便在集合中及作为 dict 的键使用
# 利用 __slots__ 节省内存
# 我们将开发一个简单的二维欧几里得向量类型,在这个过程中涵盖上述全部话题。在实现这个类型的中间阶段,我们会讨论两个概念:
# 如何以及何时使用 @classmethod 和 @staticmethod 装饰器
# Python 的私有属性和受保护属性的用法、约定和局限 # 9.1 对象表示形式
# 每门面向对象的语言至少都有一种获取对象的字符串表示形式的标准方式。Python 提供了两种方式。
# repr()
# 以便于开发者理解的方式返回对象的字符串表示形式。
# str()
# 以便于用户理解的方式返回对象的字符串表示形式。 # 9.2 再谈向量类
# 为了说明用于生成对象表示形式的众多方法,我们将使用一个Vector2d 类,它与第 1 章中的类似。
# 示例 9-1 Vector2d 实例有多种表示形式
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))
def __repr__(self):
class_name = type(self).__name__
return '{}({!r}, {!r})'.format(class_name, *self)
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)) # 示例 9-2 vector2d_v0.py:目前定义的都是特殊方法
v1=Vector2d(3,4)
print(v1.x,v1.y)
x,y=v1
print(x,y) # (3.0, 4.0)
print(v1) # Vector2d(3.0, 4.0)
v1_clone = eval(repr(v1))
print(v1 == v1_clone) # True
print(v1) # (3.0, 4.0)
octets=bytes(v1)
print(octets) # b'd\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x00\x00\x10@'
print(abs(v1)) # 5.0
print(bool(v1),bool(Vector2d(0,0))) # 9.3 备选构造方法
# 我们可以把 Vector2d 实例转换成字节序列了;同理,也应该能从字节序列转换成 Vector2d 实例。 # 示例 9-3 vector2d_v1.py 的一部分:这段代码只列出了frombytes 类方法,要添加到 vector2d_v0.py(见示例 9-2)中定义的Vector2d 类中 # 9.4 classmethod与staticmethod
# staticmethod 装饰器也会改变方法的调用方式,但是第一个参数不是特殊的值。
# 其实,静态方法就是普通的函数,只是碰巧在类的定义体中,而不是在模块层定义。 # 示例 9-4 比较 classmethod 和 staticmethod 的行为
# >>> class Demo:
# @classmethod
# def klassmeth(*args):
# ❶ klassmeth 返回全部位置参数。
# return args
# @staticmethod
# def statmeth(*args):
# ❷ statmeth 也是。
# return args
# ❸ 不管怎样调用 Demo.klassmeth,它的第一个参数始终是 Demo 类。
# >>> Demo.klassmeth()
# (<class '__main__.Demo'>,)
# >>> Demo.klassmeth('spam')
# (<class '__main__.Demo'>, 'spam')
# ❹ Demo.statmeth 的行为与普通的函数相似。
# >>> Demo.statmeth()
# ()
# >>> Demo.statmeth('spam')
# ('spam',) # 9.5 格式化显示
# 内置的 format() 函数和 str.format() 方法把各个类型的格式化方式委托给相应的 .__format__(format_spec) 方法。format_spec 是格式说明符,它是:
# format(my_obj, format_spec) 的第二个参数,或者
# str.format() 方法的格式字符串,{} 里代换字段中冒号后面的部分
# >>> br1=1/2.43
# >>> br1
# 0.4115226337448559
# >>> format(br1,'0.4f')
# '0.4115'
# >>> '1 BRL={rate:0.2f}USD'.format(rate=br1)
# '1 BRL=0.41USD' # 9.6 可散列的Vector2d # 9.7 Python的私有属性和“受保护的”属性
# Python 不能像 Java 那样使用 private 修饰符创建私有属性,但是Python 有个简单的机制,能避免子类意外覆盖“私有”属性。 # 9.8 使用 __slots__ 类属性节省空间
# 在类中定义 __slots__ 属性之后,实例不能再有__slots__ 中所列名称之外的其他属性。 # 9.9 覆盖类属性 # 9.10 本章小结
# 回看表 1-1,你会发现本章的几个代码清单说明了下述特殊方法。
# 所有用于获取字符串和字节序列表示形式的方法:__repr__、__str__、__format__ 和 __bytes__。
# 把对象转换成数字的几个方法:__abs__、__bool__和__hash__。
# 用于测试字节序列转换和支持散列(连同 __hash__ 方法)的__eq__ 运算符。 # 9.11 延伸阅读
第9章 符合Python风格的对象的更多相关文章
- 流畅的python第九章符合Python风格的对象学习记录
对象表示形式 每门面向对象的语言至少都有一种获取对象的字符串表示形式的标准方式.Python提供了两种方式 repr()便于开发者理解的方式返回对象的字符串表示形式 str()便于用户理解的方式返回对 ...
- 流畅的python学习笔记:第九章:符合python风格的对象
首先来看下对象的表现形式: class People(): def __init__(self,name,age): self.name=name self.a ...
- 流畅的python 符合python风格的对象
对象表示形式 每门面向对象的语言至少都有一种获取对象的字符串表示形式的标准方式.Python 提供了两种方式. repr() 以便于开发者理解的方式返回对象的字符串表示形式.str() 以便于用户理解 ...
- python 符合Python风格的对象
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 25.0px Helvetica } 对象表示形式 每门面向对象的语言至少都有一种获取对象的字符串表示形式的 ...
- 符合Python风格的对象
array和bytes的转换 - 每个array必须有一个type_code,以此为依据解析底层字节序列 - array有一个frombytes方法,可以把字节序列按type_code转换成Array ...
- Fluent_Python_Part4面向对象,09-pythonic-obj,Python风格的对象
第四部分第9章,Python风格的对象 这一章接第1章,说明常见的特殊方法实现. 本章包括以下话题: 支持用于生成对象其它表示形式的内置函数(如repr().bytes(),等等) 使用一个类方法实现 ...
- 流畅的python第九章笔记 python风格的python
9.1对象表示形式 __repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员. 我们打印下面的A是默认输出这个对象的类型,我们对B进行了修改_ ...
- 第8.25节 Python风格的__getattribute__属性访问方法语法释义及使用
一. 引言 在<第8.13节 Python类中内置方法__repr__详解>老猿介绍了在命令行方式直接输入"对象"就可以调用repr内置函数或__repr__方法查看对 ...
- 《Python学习手册 第五版》 -第4章 介绍Python对象类型
本章的内容主要是介绍了Python的核心对象类型,后续的5.6.7.8.9章针对这些核心类型分别展开详细的说明 本章我认为重要的有几点 1.作者有谈到Python的知识结构,这个我感觉是一个大框架,可 ...
随机推荐
- HTTP 基础
HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...
- Android Studio生成签名安装包(Generate Signed APK)
一 打开构建对话框. 二 创建新的密钥库(key store) 可以选择已创建的密钥库,也可以选择创建新的密钥库. 创建完成后,自动导入. 三 选择签名类型. 如果不选,会提示错误. 这里将新旧两种签 ...
- war包内更新文件
感谢@这个博客提供的分享 亲测有效,原文: 1.如果要替换的文件直接在war包的根目录(一级目录)下,直接使用jar uvf命令替换即可 如:替换a.war中b.xml文件 jar uvf a.war ...
- Java_8排序(冒泡排序和选择排序)
1.选择排序 package demo1; public class Demo1 { public static void main(String[] args) { int[] arr= {23,5 ...
- 如何利用git由本机向github上传文件 ssh方式的
1.直接在git bash里操作,输入命令cd ~/.ssh ls 2.如果不是这样的,说明没有生产公匙,然后输入命令 ssh-keygen -t rsa -C "自己的邮箱地址" ...
- utils.js和vue-loader.conf.js
var utils = require('./utils')var config = require('../config')var isProduction = process.env.NODE_E ...
- Oracle_PL/SQL(2) 过程控制
0.检索单行数据0.1使用标量变量接受数据例1: 7788declare v_ename emp.ename%type; v_sal emp.sal%type;begin select ename,s ...
- oracle 直接复制表内容到新表
不知道为什么,刚建的oracle数据库删除数据很慢,表里面有120多万数据,非常地慢 于是采用的复制的方法,命令如下: create table students_backup as select * ...
- sql 查询某个字段出现的次数
表名随便起个 testtable 那么有这么一个需求,利用你所学的sql语句 单表查询出下表的结果 也就是统计某个时间某个值出现的次数其实一开始我是很懵,毕竟之前也没做过,只能怪自己学得太浅了.过后我 ...
- angular2.0学习笔记4.npm常用指令记录及angular语法
以下命令,都需要在命令行窗口中,先切入到项目文件夹目录,再执行 1.npm start 这个命令会在“监听”模式下运行TypeScript编译器,当代码变化时,它会自动重新编译. 同时,该命令还会在浏 ...