[流畅的python 笔记] 第一章:python数据模型 20190925

魔术方法

特殊方法 的昵称,特其名字以两个下划线开头,以两个下划线结尾(例如 __getitem__)在类中重写魔术方法,实际上是在类中对python的内置方法进行重载.

e.g., 为了能求得my_collection[key]的值,解释器实际上会调用my_collection.__getitem__(key). 如果在某个类中,重写了__getitem__方法,那么下次再使用my_collection[key]时调用的将会是重写过的方法.

1.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]

Save as ./cards_1_1.py

>>> from cards_1_1 import FrenchDeck
>>> deck = FrenchDeck()  # 创建一个FrenchDeck类的实例
>>> len(deck)  # 重写len方法,调用重写后的方法
52

NOTE 1:

  1. 在使用len(deck)时,事实上是调用了deck.__len__().而__len__是绑定方法,因此可以自动传入self参数
  2. 在代码中,__len__方法返回的是len(self._cards)
  3. FrenchDeck 类中,self._cards是一个列表,是python内置的数据类型
  4. len(list)返回的是列表长度,因此对 FrenchDeck 类使用 len() 操作如同对列表使用一样
>>> deck[0]  # 取第一个元素
Card(rank='2', suit='spades')
>>> deck[-1]  # 取最后一个元素
Card(rank='A', suit='hearts')

NOTE 2:

  1. 实际上是通过__getitem__的方式
  2. 通过__getitem__方法,对 FrenchDeck 类使用 [ ] 操作相当于对一个列表使用 [ ] 操作。当且仅当你使用[]操作时,FrenchDeck 类的实例可以看作一个列表,所有基于列表 [ ] 的方法都可以应用在该类上
  3. __getitem__方法把 [ ] 操作交给了self._cards列表,所以 deck 类自动支持切片(slicing)操作
  4. __getitem__方法同时也将对象变成可迭代的。可以使用 for...in...,它会按顺序做一次迭代的搜索
>>> from random import choice
>>> card = choice(deck)
>>> card
Card(rank='8', suit='hearts')

NOTE 3:

用 python 内置的 random 模块,其中的 random.choice() 方法来随机取一个元素

note_1: str.split( ) 以空格为分隔符,包含\n, 返回分割后的字符串列表.

note_2: namedtuplecollections 模块中定义的数据类型. Python拥有一些内置的数据类型(str,int,list,tuple,dict, etc),而collections模块在这些内置数据类型的基础上,提供了额外的数据类型.

collections.namedtuple

  1. namedtuple 是继承自 tuple 的子类,namedtuple 创建一个和 tuple 类似的对象
  2. 该对象拥有自己的名称. 它更像是一个带有多个数据属性的类,不过里面的数据是只读的.
  3. 用namedtuple可以很方便的定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用.

Taking nameetuple for example:

from collections import namedtuple
 
Tpoint=namedtuple("Tpoint",["x","y"])
p=Tpoint(x=10,y=20)
print(p.x)
# 10
print(p.y)
# 20
print(p[0])
# 10
print(p[1])
# 20
 
# 把数据变成namedtuple类:_make
t=[11,21]
p=Tpoint._make(t)
print(p)
# Tpoint(x=11, y=21)
 
# 将字典变为namedtuple
dic={"x":30,"y":40}
dic_tuple=Tpoint(**dic)
print(dic_tuple)
# Tpoint(x=30, y=40)

你可能感兴趣的:(fluent,python)