-
特殊方法
python 特殊方法又叫魔术方法,双下方法,例如 __getitem__、__len__。这些方法体现了“python 风格”,代表了 python 强大的设计思想。而且,python 内置类在使用特殊方法时速度更快。下面以扑克牌类来说明特殊方法:
from collections import namedtuple
Card = 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):
# _cards: private variable
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
return self._cards[position]
1. __getitem__
如果你的类对象包含这一方法,那么该类对象是可迭代的。如果你想要访问某一张牌,可以直接采用:
>>deck = FrenchDeck()
>>deck[0]
Card(rank='2', suit='spades')
2. __len__
访问可迭代对象的长度。
>>len(deck)
52
特殊方法是为了被python解释器调用,我们不能直接调用他们,例如错误使object.__getitem__,而应该直接使用len(object)。
你也可以查看其他特殊方法:
print(dir(str))
-
% 和 str.format
% 和 str.format是格式化字符串的两种方法,在《流畅的python》一书中,str.format是最新的使用方式,而%则比较陈旧,但并没说两者有何优劣,所以,选择其一使用即可。下面给出一些例子:
# %
# %r 使用__repr__, %s 使用__str__
>>print("choose a deck indexing 0: %r, %r" % (deck[0].rank, deck[0].suit))
choose a deck indexing 0: '2', 'spades'
>>print("choose a deck indexing 0: %s, %s" % (deck[0].rank, deck[0].suit))
choose a deck indexing 0: 2, spades
# str.format
#使用{}占位符
>>print('I\'m {},{}'.format(deck[0].rank, deck[0].suit))
I'm 2,spades
# 使用位置占位符
>>print('I\'m {0},{1}'.format(deck[0].rank, deck[0].suit))
>>print('I\'m {1},{0}'.format(deck[0].rank, deck[0].suit))
I'm 2,spades
I'm spades,2
#使用'{name}'形式的占位符
>>print('Hi,{name},{message}'.format(name=deck[0].rank, message=deck[0].suit))
关于__repr__和__str__,看这个帖子:
https://stackoverflow.com/questions/1436703/what-is-the-difference-between-str-and-repr
-
列表推导和生成器表达式
1. 对于列表推导,一般只用于创建列表。如:
>>symbols = "!@#$%^"
>>codes = [ord(symbol) for symbol in symbols]
>>print(codes)
[33, 64, 35, 36, 37, 94]
笛卡尔积:
>>colors = ['black', 'white']
>>sizes = ['L', 'M', 'S']
>>tshirts = [(color, size) for color in colors for size in sizes]
>>print(tshirts)
[('black', 'L'), ('black', 'M'), ('black', 'S'), ('white', 'L'), ('white', 'M'), ('white', 'S')]
2. 生成器表达式
注意与上文中列表推导的输出方式的差别。列表推导的结果是产生一个固定长度的列表,而生成器表达式不会。
>>tshirts_tuple = ((color, size) for color in colors for size in sizes)
>>for tshirt in tshirts_tuple:
>> print(tshirt)
('black', 'L')
('black', 'M')
('black', 'S')
('white', 'L')
('white', 'M')
('white', 'S')
-
元组拆包
# 最简单的:
>>lax_coordinates = (13.02, 25.426)
>>latitude, longitude = lax_coordinates
>>print(latitude)
>>print(longitude)
13.02
25.426
# *处理多个元素
>>a, b, *rest = range(5)
>>print(a, b, rest)
0 1 [2, 3, 4]
-
具名元组
collections中的namedtuple类可以用来构建一个带字段名的元组和一个有名字的类。
from collections import namedtuple
# 创建格式 ('类名', [字段名1, 字段名2,...]])
Card = namedtuple('Card', ['rank', 'suit'])
-
序列中使用+和*
+和* 不会修改原有操作,而是创建一个全新的序列
>>l = [1, 2, 3]
>>print(l * 5)
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
# 注意,尽量不要使用其他对象的引用来创建
若要操作只含数字的列表,那么array.array比list更高效
快速序列化: pickle
待更...