Python学习笔记整理

前言:大四刚刚毕业,学的土木可是很喜欢编程,奈何进的互联网运营岗,琢磨着转岗,工科出身的还是想做技术。从六月份学了这么久,不写些博客沉淀一下技术,感觉都忘光了,不多说了。以后详细介绍。。。

第一章 Python数据类型(想到哪里写哪里)

Python这门语言我最喜欢的还是他的一致性,如果你学过其他语言,可能会对len(colleciton)而不是collection.len()写法觉得不适合。其实这就是我一直不理解的PythonIC,Python风格的关键。这种设计思想完全体现在Python的数据类型上。而数据模型所描述的API,为使用最地道的语言特性来构建你自己的对象提供了工具。

数据模型其实是对Python框架的描述,他规范了这门语言自身构建模块的借口,这些模块包括但不限于序列,迭代器,函数,类,和上下文管理器。不管在那种框架下写程序,都会花费大量时间去实现那些被框架本身调用的方法,Python也不例外。Python解释器碰到特殊的语句时,会使用特殊的方法去激活一些基本的对象操作,这些特殊方法的名字以双下划线形式(__getitem__)。比如obj[key]的背后就是__getitem__方法,为了能求得my_collection[key]的值,解释器实际上会调用my_collection._collection.__getitem__(key)。

这些特殊方法名能让你自己的对象实现和支持以下的语言构架,并与之交互:

  1. 迭代
  2. 集合类
  3. 属性访问
  4. 运算符重载
  5. 函数和方法的调用
  6. 对象的创建和销毁
  7. 字符串表示形式和格式化
  8. 管理上下文(with模块)

magic和dunder

魔法函数(magic method)是特殊方法的昵称。有些Python开发者在提到__getitem__这个魔法函数的时候,会用“下划线-下划线-getitem"这种说法,但是显然这种说法有点问题,因为像__x这种命名在Python里还有其他含义(Python的私有属性,这个可能后边会写)。

一摞Python风格的纸牌

接下来我会用一个非常简单的例子来展示如何实现__getitem__和__len__着两个魔法函数,通过这个例子也能看到魔法函数的强大之处。

# 一摞有序的纸牌


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]
首先,我们用collections.namedtuple 构建了一个简单的类来表示一张纸牌。自Python2.6开始,nametuple就加入了Python中,用以构建只要少数属性但没有方法的对象,比如数据库条目。----
说道这里我想说一下,collections模块
collections模块是Python内建的一个集合模块,提供了很多有用的集合类。
namedtuple
nametuple是一个函数,他用来创建一个自定义的元组对象,并且规定了元组元素的个数,并可以用属性而不是索引来引用元组的某个元素。可以通过nametuple来定义一种数据类型,它具备元组的不变性,又可以根据属性来引用,十分方便。
     >>> from collections import nametuple
     >>>Mytuple = nametuple('Mytuple',['Mytuple',['x','y'])
     >>>n = Mytuple(11,22)
     >>>n.x
     11
    >>>n.y
     22

deque模块
使用list存储数据结构时,按照索引访问元素很快,但是插入和删除元素就很慢了,因为list时线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适用于队列和栈。
>>> from collections import deque
>>> q = deque(['a','b','c'])
>>> q.append('x') #默认添加列表最后一项
>>> q.appendleft('y') #添加到列表第一项
>>> q
deque(['y','a','b','c','x'])
>>>q.pop() #默认删除列表最后一个元素
'x'
>>>q.popleft() #删除列表的第一个元素
'y'
>>> 9
deque(['a','b','c'])


OrderedDict模块

有序字典的应用。OrderedDict的有序性是按照插入的顺序,而不是KEY的顺序。
>>>from collections import OrderedDict
>>>d = dict(['a',1),('b',2),('c',3)])
>>>d # dict的key是无序的
'a':1,'c':3,'b':2}
>>> od = OrderedDict([('a',1),('b',2),('c',3)])
>>> od # OrderedDict的key是有序的
OrdereDict([('a',1),('b',2),('c',3)])
通过OrderedDict可以实现一个FIFO(先进先出)的字典,当容量超出限制后,先删除最早添加的KEY。
from collections import OrderedDict

---
class LastUpdatedOrderedDict(OrderedDict):

def __init__(self, capacity):
super(LastUpdatedOrderedDict, self).__init__()
self._capacity = capacity

def __setitem__(self, key, value):
containsKey = 1 if key in self else 0
if len(self) - containsKey >= self._capacity:
last = self.popitem(last=False)
print('remove:', last)
if containsKey:
del self[key]
print('set:', (key, value))
else:
print('add:', (key, value))
OrderedDict.__setitem__(self, key, value)


Counter
简单的计数器

>>>from collections import OrdereDict
>>>c = Counter()
>>>for ch in 'programming':
... c[ch] = C[ch] + 1
...
>>> c
Counter ('g:2','m':2,'r':2,'a',1,'i':1,'o':1,'n':1,'p':1})


defaultdict
使用字典时,如果引用KEY不存在,就会抛出KEYERROR,如果希望key不存在时,返回一个默认值,就可以用defaultdict
>>> from collections import defaultdict
>>> Mydict = defaultdict(lambda:'N/A')
>>> Mydict['key1'] = 'abc'
>>> Mydict['key1'] #字典的key1存在
'abc'
>>> Mydict['key2']#字典的key2不存在,返回默认值为'N/A'
'N/A'
注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入。除了key不存在而返回默认值,其他功能与普通字典无异。


然后我们继续说卡牌的事儿,写跑偏了。。。。。。


首先,我们用collections.namedtuple构建了一个简单的类来表示一张卡牌。自Python2.6开始,namedtuple就加入到Python了。用以构建只有少数属性但是没有方法的对象,比如数据库条目。如下面这个终端所示,利用nametuple,我们可以
很容易的得到一个纸牌对象:


>>>beer_card = Card('7','diamonds')
>>>beer_card
Card(rank='7',suit='diamonds')
当然,我们这个例子主要还是关注FrenchDeck这个类,它即短小又精悍。首先,他跟任何标准Python集合类型一样,可以用len()函数来查看一叠拍有多少张?
>>>deck = FrenchDeck
>>>len(deck)
52

从一叠牌中抽取特定的一张纸牌,比如说第一张或者最后一张,是很容易的:deck[0]或deck[-1].这都是由__getitem__方法提供的:
>>>deck[0]
Card(rank='2',suit='spades')
>>>deck[-1]
Card(rank='A',suit='hearts')
我们需要单独写一个方法用来随机抽取一张纸牌吗?没必要,Python已经内置了从一个序列中随你选出一个元素的函数random.choice,我们直接把它用在这一摞纸牌实例上就好:
>>> from random import choice
>>> choice(deck)
Card(rank='3',suit='hearts')
>>>choice(deck)
Card(rank='k',suit='spades')
>>>choice(deck)
Card(rank='2',suit='clubs')
  • 现在已经可以体会到通过实现特使方法来利用Python数据模型的两个好处。
    • 作为你的类的用户,他们不必去记住标准操作的格式名称("怎么得到的元素的总数?"是.size()还是.length()还是别的什么?”)。
      • 可以更加方便的利用Python的标准库,比如random.choice函数,从而不用重新发明轮子。

 


猜你喜欢

转载自www.cnblogs.com/hl1996-11-24/p/9276772.html