我是靠谱客的博主 凶狠天空,最近开发中收集的这篇文章主要介绍《Fluent Python》读书笔记——第一章Python数据模型摘要示例1 一摞Python风格的纸牌示例2 二维向量类,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

摘要

这一章主要通过几个例子向读者展示了怎么通过定义特殊方法,使自定义的数据类型可以表现的跟内置类型一样,写出更具有Python风格的代码。

示例1 一摞Python风格的纸牌

import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
class FrenchDeck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit) for suit in self.suits
for rank in self.ranks]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]

由于定义了__len__方法,所以,当实例化一摞纸牌后,可以len()来查看这个摞纸牌有多少张。

	>>> deck = FrenchDeck()
>>> len(deck)
52

如果没有定义__len__方法,运行上述代码则会报错TypeError: object of type 'FrenchDeck' has no len()

同样的,由于定义了__getitem__这个特殊方法,可以使用deck[0]的方式从这摞扑克中抽取任意一张。

	>>> deck[0]
Card(rank='2', suit='spades')
>>> deck[1]
Card(rank='3', suit='spades')

如果没有定义__getitem__个特殊方法,同样也会报错:TypeError: 'FrenchDeck' object is not subscriptable
同时由于实现了__getitem__方法,这摞扑克也变成可迭代的了,并且也支持切片操作。

>>> for card in deck:
print(card)
Card(rank='2', suit='spades')
Card(rank='3', suit='spades')
Card(rank='4', suit='spades')
...
>>> deck[:3]
[Card(rank='2', suit='spades'), Card(rank='3', suit='spades'),
Card(rank='4', suit='spades')]

通过实现 __len____getitem__这两个特殊方法, FrenchDeck就跟一个 Python 自有的序列数据类型一样,可以体现出 Python 的核心语言特性(例如迭代和切片)。同时这个类还可以用于标准库中诸如random.choicereversedsorted 这些函数。

示例2 二维向量类

from math import hypot
class Vector:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __repr__(self):
return 'Vector(%r, %r)' % (self.x, self.y)
def __abs__(self):
return hypot(self.x, self.y)
def __bool__(self):
return bool(abs(self))
def __add__(self, other):
x = self.x + other.x
y = self.y + other.y
return Vector(x, y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)

__repr__

Python有一个内置的函数叫 repr,它能把一个对象用字符串的形式表达出来以便辨认,这
就是“字符串表示形式”。 repr 就是通过 __repr__ 这个特殊方法来得到一个对象的字符串
表示形式的。如果没有实现 __repr__,当我们在控制台里打印一个向量的实例时,得到的
字符串可能会是 <Vector object at 0x10e100070>。通过定义__repr__方法,我们就可以让这个对象的字符串表示形式显示成我们想要任何样子。

__repr____str__ 的区别在于,后者是在 str() 函数被使用,或是在用 print 函数打印一个对象的时候才被调用的,并且它返回的字符串对终端用户更友好。如果你只想实现这两个特殊方法中的一个, __repr__ 是更好的选择,因为如果一个对象没有 __str__ 函数,而 Python 又需要调用它的时候,解释器会用 __repr__ 作为替代。

__add____mul__

通过__add____mul__,该向量类的实例化对象可以实现 + 和 * 。

更多的特殊方法可以参考python文档中的Data Model部分https://docs.python.org/3/reference/datamodel.html

类别方法名
字符串/字节序列表示形式__repr____str____format____bytes__
数值转换__abs____bool____complex____int____float____hash____index__
集合模拟__len____getitem____setitem____delitem____contains__
迭代枚举__iter____reversed____next__
可调用模拟__call__
上下文管理__enter____exit__
实例创建和销毁__new____init____del__
属性管理__getattr____getattribute____setattr____delattr____dir__
属性描述符__get____set____delete__
跟类相关的服务__prepare____instancecheck____subclasscheck__

最后

以上就是凶狠天空为你收集整理的《Fluent Python》读书笔记——第一章Python数据模型摘要示例1 一摞Python风格的纸牌示例2 二维向量类的全部内容,希望文章能够帮你解决《Fluent Python》读书笔记——第一章Python数据模型摘要示例1 一摞Python风格的纸牌示例2 二维向量类所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部