python最好的品质之一就是一致性。初步接触python可能会len(collection)而不是collection.len()觉得不适应,这是通常所说的“python风格”(Pythonic)的关键,体现在Python的数据模型上,数据模型是对Python框架的描述,它规范了这门语言自身构建模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。

特殊方法:以两个下划线开头,两个下划线结尾(例如__getitem__)。比如obj[key]背后就是__getitem__方法,为了能求得my_collection[key]的值,解释器实际上会调用my_collection.__getitem__(key)。

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构建了一个简单的类表示一张纸盘,用以构建只有少数属性但是没有方法的对象,比如数据库条目。

>>> beer_card = Card('', 'diamods')
>>> beer_card
Card(rank='', suit='diamods')

用len()函数看看一叠牌有多少张:

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

从一叠牌中抽取特定的一张,比如第一张或者是最后一张,以下这些都是由__getitem__方法提供的:

>>> deck[0]
Card(rank='', suit='spades')
>>> deck[-1]
Card(rank='A', suit='hearts')
>>>

也可以随机抽取一张纸牌

>>> from random import choice
>>> choice(deck)
Card(rank='', suit='clubs')
>>> choice(deck)
Card(rank='', suit='clubs')
>>> choice(deck)
Card(rank='', suit='diamonds')

这是因为__getitem__方法把[]操作交给了self._cards列表,所以deck类会自动支持切片操作。

>>> deck[:3]
[Card(rank='', suit='spades'), Card(rank='', suit='spades'), Card(rank='', suit='spades')]
>>> deck[12::13]
[Card(rank='A', suit='spades'), Card(rank='A', suit='diamonds'), Card(rank='A', suit='clubs'), Card(rank='A', suit='hearts')]

另外仅仅实现了__getitem__方法,这一摞牌就变成可迭代了

>>> for card in deck:
... print(card)
...
Card(rank='', suit='spades')
Card(rank='', suit='spades')
...

in运算符会按照顺序做迭代搜索,

>>> Card('Q', 'hearts') in deck
True
>>> Card('', 'beasts') in deck
False

排序,按照黑桃最大、红桃次之、方块再次、梅花最小

>>> suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
>>> def spades_high(card):
... rank_value = FrenchDeck.ranks.index(card.rank)
... return rank_value * len(suit_values) + suit_values[card.suit]
...
>>> for card in sorted(deck, key=spades_high):
... print(card)
...
Card(rank='', suit='clubs')
Card(rank='', suit='diamonds')
Card(rank='', suit='hearts')

按照目前的设计,FrenchDeck是不能洗牌的。

如何使用特殊方法

特殊方法的存在是为了被Python解释器调用的,是隐式的,并不需要调用他们。也就是说没有my_object.__len__()这种写法,而应该是len(my_object)。如果是Python内置的类型,比如列表list、字符串str,等,那么__len__会直接返回ob_size属性。

比如for i in x:这个语句,背后用的是iter(x),而这个函数的背后则是x.__iter__()方法。

通常代码无需直接使用特殊方法,除了__init__方法。

通过内置的函数(例如len、iter、str等等)来使用特殊方法是最好的选择,他们的速度更快。

另外不要自己想当然地随意添加特殊方法,比如__foo__之类的,因为虽然现在这个名字没有被Python内部使用,以后就不一定了。

字符串表达形式

python有一个内置的函数是repr,它能把一个对象用字符串的形式表达出来以便辨认。

%和str.format这两种格式化字符串的方法目前都在使用,但是str.format可能会越来越适用。

__repr__和__str__的区别在于,后者是在str()函数被使用,或者是在print函数打印才被调用的,并且返回的字符串对终端用户更友好。如果只想实现这两种中的一种,那么__repr__会是更好的选择。

流畅的python--python数据模型的更多相关文章

  1. python --- Python中的callable 函数

    python --- Python中的callable 函数 转自: http://archive.cnblogs.com/a/1798319/ Python中的callable 函数 callabl ...

  2. Micro Python - Python for microcontrollers

    Micro Python - Python for microcontrollers MicroPython

  3. 从Scratch到Python——python turtle 一种比pygame更加简洁的实现

    从Scratch到Python--python turtle 一种比pygame更加简洁的实现 现在很多学校都开设了Scratch课程,学生可以利用Scratch创作丰富的作品,然而Scratch之后 ...

  4. 从Scratch到Python——Python生成二维码

    # Python利用pyqrcode模块生成二维码 import pyqrcode import sys number = pyqrcode.create('从Scratch到Python--Pyth ...

  5. [Python]Python 使用 for 循环的小例子

    [Python]Python 使用 for 循环的小例子: In [7]: for i in range(5): ...: print "xxxx" ...: print &quo ...

  6. [python]python 遍历一个list 的小例子:

    [python]python 遍历一个list 的小例子: mlist=["aaa","bbb","ccc"]for ss in enume ...

  7. [Python]Python日期格式和字符串格式相互转换

    由字符串格式转化为日期格式的函数为: datetime.datetime.strptime() 由日期格式转化为字符串格式的函数为: datetime.datetime.strftime() # en ...

  8. [python]Python 字典(Dictionary) update()方法

    update() 函数把字典dict2的键/值对更新到dict里.如果后面的键有重复的会覆盖前面的语法dict.update(dict2) dict = {'Name': 'Zara', 'Age': ...

  9. 流畅的python python 序列

    内置序列 容器类型 list .tuple和collections.deque这些序列能放入不同的类型的数据 扁平序列 str.byets.bytearray.memoryview(内存视图)和arr ...

  10. [python]python try异常处理机制

    #python的try语句有两种风格 #一:种是处理异常(try/except/else) #二:种是无论是否发生异常都将执行最后的代码(try/finally) try/except/else风格 ...

随机推荐

  1. JS实现控制HTML5背景音乐播放暂停

    首先在网页中嵌入背景音乐,html5代码为: <script src="http://wuover.qiniudn.com/jquery.js"></script ...

  2. Microsoft Azure Machine Learning Studio

    随着机器学习(ML)成为软件行业的主流,重要的是要了解它的工作原理,并将其置于开发栈中.了解如何为您的应用程序构建ML服务,您可以确定您的ML应用程序中的机会,实施ML,并与您的团队的ML专业人士清楚 ...

  3. 前端base64、baseurl加解密和RSA加解密

    由于项目最近要进行安全测试,前端的用户和密码都是明文数据传送给后台那里,其实这样很很不安全的,容易泄露个人信息和密码.中间服务器的同事就提出,可以通过前端接收公钥,利用公钥对密码进行加密,把加密过密码 ...

  4. ubuntu系统备份与恢复-remastersys方法

    http://blog.csdn.net/yaoqi_isee/article/details/73730010 http://blog.csdn.net/handsome_sheng/article ...

  5. 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\2da42acc\ab2935

    未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\2da42acc\ab293 ...

  6. python源码编译

    PyInstaller是一个基于windows平台,将源码打包成执行文件的第三方库,PyInstaller本身并不属于Python包. 源文件要采用UTF-8编码 安装Pyinstaller pip ...

  7. HDU - 3917(朴素LIS + 最大流)

    题意: 求出所有的最长上升子序列的个数且每个元素只能用一次 解析: 呵...呵...呵..呵..emm... 再见 我死了...wa了15发之后...原来不能用~  要用 != EOF 这题算水题吧. ...

  8. 【XSY2750】Mythological V 2-sat

    题目描述 有一棵\(n\)个点的树,还有\(m\)个物品. 你要把每个物品放在树上的一个点上(两个物品可以放在同一个点). 有\(q\)个限制:\(a,b\)两个物品在路上的最短路经过\(c\). 要 ...

  9. pytorch kaggle 泰坦尼克生存预测

    也不知道对不对,就凭着自己的思路写了一个 数据集:https://www.kaggle.com/c/titanic/data import torch import torch.nn as nn im ...

  10. 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)

    Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...