python使用特殊方法创建类
用python的内置特殊方法创建类可以使自定义的类更像python内置的数据结构,如(list,tuple,set,dict) 这样在后续代码中调用自定义类的时候就可以不用类中自己封装的方法,而使用通用的方法即可以得到结果
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 rank in ranks
for suit in suits]
def __len__(self):
return len(self._cards)
def __getitem__(self,position):
return self._cards[position]
- collections模块是python的一个内置集合模块,提供了很多有用的集合类
tuple表示元组,是一个不可改变的集合,而namedtuple用于构建只有少数属性但是没有办法的对象,例如构造一个点的坐标
p = (1,2)
但是很难知道这是一个点的坐标,而定义一个Points类又显得小题大做(因为Points类中不需要方法),这时候就可以用namedtuplefrom collection import namedtuple
Point = namedtuple('Point',['x','y'])
p = Point(1,2)
p.x
1
p.y
2
p
Point(1,2)
用了特殊方法定义一个类之后就可以用len()直接求数量,这是因为当对FrenchDeck()类调用len时即对类中封装的 __len__特殊方法进行调用来得到数量
>>> deck = FrenchDeck()
>>> len(deck)
52
这里给出用特殊方法来利用Python数据模型的两个好处(流畅的Python)
- 作为你类的用户,他们不必去记住标准操作各式名称(如自己定义类中 .len(), .size() 等)
- 可以更加方便的使用Python的标准库,比如random.choice函数,而不用重新发明轮子
用__getitem__()方法可以把[]操作给self._cards列表,故deck类自动支持切片等操作
用特殊方法实现运算符重载
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)