流畅的Python学习记录(1)
流畅的Python学习记录(1)——Python的数据类型
标签(空格分隔): Python 高性能
经过了半年多的实习,深感之前学习的Python只是知其然而不是知其所以然,因此实习之后回到学校,有了许多空闲的时间,便多抽出一些时间来充实一下自己的编程武器库。经过一系列的调研工作,感觉《流畅的Python》这本书对Python的进阶非常有用,因此开始了Python的进阶学习。
- Python数据模型的特殊方法
Python的特殊方法
Python作为一门面向对象的语言,它也秉承了一切皆为对象的理念,无论是列表、元祖、字典都可以将其当作对象,而对这些对象的一些操作,如len(), sort(), 并不是像C++那样,需要在对象内部定义或者继承父类的方法。比如说有一个对象obj,obj.len()是典型的C++、Java式的调用方法,而Python则是len(obj)。当Python遇到类似特殊的方法时,会去调用它自身的特殊方法,在Python中,特殊方法以两个下划线打头,两个下划线结尾(如__getitem__()方法)。而这些特殊方法可以帮助你实现很多方便的操作,比如说迭代、运算符重载、打印对象等等。
接下来我们用一段代码说明特殊方法的妙用,我们的目的是创建一个成副的纸牌类,纸牌类里含有所有52张纸牌:
import collections
Card = collections.namedtuple("Card", ["rank", "suit"])//创建一对具名元祖
class FrenchDick(object):
ranks = [ n for n in range(2,11) ] + list("JQKA")
suits = "spades diamonds clubs hearts".split()
def __init__(self):
self._card = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
print "len function!!!"
return len(self._card)
def __getitem__(self, item):
print "getitem function!!!"
return self._card[item]
我们首先对具名元祖做一个简单的解释,我个人对具名元祖的理解是类似于C语言中的struct结构体,即它本身是一个元祖,却能使用数据名而不仅仅是下标来访问内部的数据。
有了这个类之后,我们可以这样来操作属于这个类的对象
>>>dick = FenchDick()
>>>dick[0]
getitem function!!!
Card(rank=2, suit='spades')
>>>len(dick)
len function!!!
52
不仅仅如此,实现了特殊方法__getitem__,这个类就变成可迭代的了:
>>>for card in filter(lambda x: x.suit == "spades", dick):
print card
len function!!!
getitem function!!!
getitem function!!!
.....
Card(rank=2, suit='spades')
Card(rank=3, suit='spades')
Card(rank=4, suit='spades')
Card(rank=5, suit='spades')
Card(rank=6, suit='spades')
Card(rank=7, suit='spades')
Card(rank=8, suit='spades')
Card(rank=9, suit='spades')
Card(rank=10, suit='spades')
Card(rank='J', suit='spades')
Card(rank='Q', suit='spades')
Card(rank='K', suit='spades')
Card(rank='A', suit='spades')
为了说明特殊方法我们使用了常用的两个特殊方法,而还有许多功能强大的特殊方法等待我们去挖掘。
PS:列出常用的特殊方法:
下面再来写一个自定义的二维向量类,这个二维向量类可以实现二维向量的相加相减、求出二维向量的模,本身乘除、比较(利用模值)、以及打印出自己的值:
from math import hypot
class Vector(object):
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 __add__(self, other):
x = self.x + other.x
y = self.y + other.y
return Vector(x,y)
def __mul__(self, other):
x = self.x - other.x
y = self.y - other.y
return Vector(x,y)
def __lt__(self, other):
return abs(self) < abs(other)