日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

流畅的python第一章_《流畅的Python》第一章学习笔记

發布時間:2025/3/15 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 流畅的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')

suites = '黑桃>紅桃>方塊>梅花'.split('>')

def __init__(self):

# 具名元祖實例化

self._cards = [Card(rank, suit)

for suit in self.suites

for rank in self.ranks]

def __len__(self):

return len(self._cards)

def __getitem__(self, item):

"""

可迭代

把[]操作交給self._cards列表,支持切片操作

:param item:

:return:

"""

# 具名元祖支持索引取值

return self._cards[item]

def spades_high(card):

"""

排序

2最小,A最大

黑桃>紅桃>方塊>梅花

:param card:

:return:

"""

suit_values = {

"黑桃": 3,

"紅桃": 2,

"方塊": 1,

"梅花": 0

}

rank_value = FrenchDeck.ranks.index(card.rank)

return rank_value * len(suit_values) + suit_values[card.suit]

if __name__ == '__main__':

c = Card(1, 2)

print(c[1])

f = FrenchDeck()

print(len(f)) # 52 = (11 - 2 + 4) * 4

print(f[0]) # Card(rank='2', suit='spades')

print(f[:3]) # [Card(rank='2', suit='spades'), Card(rank='3', suit='spades'), Card(rank='4', suit='spades')]

for i in f:

print(i)

for i in reversed(f):

print(i)

for i in sorted(f, key=spades_high):

print(i)

具名元祖自 Python 2.6 開始,namedtuple 就加入到 Python 里,用以 構建只有少數屬性但是沒有方法的對象

在官方文檔中也翻譯為命名元祖

它賦予了每個位置一個含義,提供可讀性和自文檔性。通過名字獲取值

通過索引值獲取值

導入方法from collections import namedtuple

具名元祖源碼閱讀返回一個新的元組子類,名為 typenametest = namedtuple('mytest','test1 test2')

t = test(1, 2)

type(t) # __main__.mytestfield_names用空白或逗號分隔開元素名if isinstance(field_names, str):

field_names = field_names.replace(',', ' ').split()

field_names = list(map(str, field_names))rename為真時, 無效字段名會自動轉換成位置名。有效字段名:除了下劃線開頭的那些任何有效的Python 標識符。有效標識符由字母,數字,下劃線組成,但首字母不能是數字或下劃線,另外不能是關鍵詞

比如 ['abc', 'def', 'ghi', 'abc'] 轉換成 ['abc', '_1', 'ghi', '_3'] , 消除關鍵詞 def 和重復字段名 abc

isidentifier:判斷字符串是否是有效的 Python 標識符,可用來判斷變量名是否合法

iskeyword:包含全部關鍵字的凍結的集合from keyword import iskeyword as _iskeyword

if rename:

seen = set()

for index, name in enumerate(field_names):

if (not name.isidentifier()

or _iskeyword(name)

or name.startswith('_')

or name in seen):

field_names[index] = f'_{index}'

seen.add(name)defaults:默認值test = namedtuple('mytest', 'test1 test2', defaults=[1, 2])

test().test1 # 1

test().test2 # 2

test = namedtuple('mytest', 'test1 test2 test3', defaults=[1, 2])

test(0).test1 # 0

test(0).test2 # 1

test(0).test3 # 2module:設置 module 屬性值if module is None:

try:

module = _sys._getframe(1).f_globals.get('__name__', '__main__')

except (AttributeError, ValueError):

pass

if module is not None:

result.__module__ = moduletest = namedtuple('mytest', 'test1 test2 test3', module='aaa')

type(test(1, 2, 3)) # aaa.mytest_make:類方法從存在的序列或迭代實例創建一個新實例@classmethod

def _make(cls, iterable):

result = tuple_new(cls, iterable)

if _len(result) != num_fields:

raise TypeError(f'Expected {num_fields} arguments, got {len(result)}')

return resultPoint = namedtuple('Point', ['x', 'y'])

t = [11, 22]

Point._make(t)# Point(x=11, y=22)_asdict:返回一個新的字典def _asdict(self):

'Return a new dict which maps field names to their values.'

return _dict(_zip(self._fields, self))p = Point(x=11, y=22)

p._asdict()# {'x': 11, 'y': 22}_replace將指定域替換為新的值def _replace(self, /, **kwds):

result = self._make(_map(kwds.pop, field_names, self))

if kwds:

raise ValueError(f'Got unexpected field names: {list(kwds)!r}')

return resultp = Point(x=11, y=22)

p._replace(x=33) # Point(x=33, y=22)_fields:列出字段名p._fields #('x', 'y')_field_defaults:字典將字段名稱映射到默認值Account = namedtuple('Account', ['type', 'balance'], defaults=[0])

Account._field_defaults# {'balance': 0}def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None):

"""Returns a new subclass of tuple with named fields.

>>> Point = namedtuple('Point', ['x', 'y'])

>>> Point.__doc__ # docstring for the new class

'Point(x, y)'

>>> p = Point(11, y=22) # instantiate with positional args or keywords

>>> p[0] + p[1] # indexable like a plain tuple

33

>>> x, y = p # unpack like a regular tuple

>>> x, y

(11, 22)

>>> p.x + p.y # fields also accessible by name

33

>>> d = p._asdict() # convert to a dictionary

>>> d['x']

11

>>> Point(**d) # convert from a dictionary

Point(x=11, y=22)

>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields

Point(x=100, y=22)

"""

# Validate the field names. At the user's option, either generate an error

# message or automatically replace the field name with a valid name.

if isinstance(field_names, str):

field_names = field_names.replace(',', ' ').split() # 將逗號轉換為空格后進行切割

field_names = list(map(str, field_names)) # 將列表中的全部內容轉換為字符串類型

typename = _sys.intern(str(typename)) # 字符串駐留:提高字符串效率.同樣的字符串對象僅僅會保存一份,放在一個字符串儲蓄池中,是共用的

if rename:

"""

無效字段名會自動轉換成位置名

"""

seen = set()

for index, name in enumerate(field_names):

if (not name.isidentifier()

or _iskeyword(name)

or name.startswith('_')

or name in seen):

field_names[index] = f'_{index}'

seen.add(name)

for name in [typename] + field_names:# 判斷各個字段都是有效字段

if type(name) is not str:

raise TypeError('Type names and field names must be strings')

if not name.isidentifier():

raise ValueError('Type names and field names must be valid '

f'identifiers: {name!r}')

if _iskeyword(name):

raise ValueError('Type names and field names cannot be a '

f'keyword: {name!r}')

seen = set()

for name in field_names:

if name.startswith('_') and not rename:# 有下劃線開頭的內容會報錯

raise ValueError('Field names cannot start with an underscore: '

f'{name!r}')

if name in seen:# 有重復的內容會報錯

raise ValueError(f'Encountered duplicate field name: {name!r}')

seen.add(name)

field_defaults = {}

if defaults is not None:

defaults = tuple(defaults)

if len(defaults) > len(field_names):# 默認值長度大于總長度時候報錯

raise TypeError('Got more default values than field names')

field_defaults = dict(reversed(list(zip(reversed(field_names),

reversed(defaults)))))# 從后往前賦值

# Variables used in the methods and docstrings

field_names = tuple(map(_sys.intern, field_names)) # 轉換為元祖

num_fields = len(field_names)

arg_list = repr(field_names).replace("'", "")[1:-1]

# repr(field_names):'(\'rank\', \'suit\')'

# .replace("'", "")[1:-1]:變為 'rank, suit'

repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')'

# '(rank=%r, suit=%r)'

tuple_new = tuple.__new__ 'rank, suit'

_dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip

# Create all the named tuple methods to be added to the class namespace

s = f'def __new__(_cls, {arg_list}): return _tuple_new(_cls, ({arg_list}))' # __new__的時候將內容變為元祖,后續訪問的時候可以用索引來查找內容

namespace = {'_tuple_new': tuple_new, '__name__': f'namedtuple_{typename}'}

# Note: exec() has the side-effect of interning the field names

exec(s, namespace)# 動態執行 Python 代碼 補充namespace的__new__方法

__new__ = namespace['__new__']

__new__.__doc__ = f'Create new instance of {typename}({arg_list})' # 為__new__方法添加說明

if defaults is not None:

__new__.__defaults__ = defaults

@classmethod

def _make(cls, iterable): # 定義_make方法

result = tuple_new(cls, iterable)

if _len(result) != num_fields:

raise TypeError(f'Expected {num_fields} arguments, got {len(result)}')

return result

_make.__func__.__doc__ = (f'Make a new {typename} object from a sequence '

'or iterable')# 為_make添加說明

def _replace(self, /, **kwds): # 定義_replace方法

result = self._make(_map(kwds.pop, field_names, self))

if kwds:

raise ValueError(f'Got unexpected field names: {list(kwds)!r}')

return result

_replace.__doc__ = (f'Return a new {typename} object replacing specified '

'fields with new values')# 為_replace方法添加說明

def __repr__(self):# 定義__repr__方法 在print的時候調用

'Return a nicely formatted representation string'

return self.__class__.__name__ + repr_fmt % self

def _asdict(self): # 定義_asdict方法 轉換成字典輸出

'Return a new dict which maps field names to their values.'

return _dict(_zip(self._fields, self))

def __getnewargs__(self):

'Return self as a plain tuple. Used by copy and pickle.'

return _tuple(self)

# Modify function metadata to help with introspection and debugging

for method in (__new__, _make.__func__, _replace,

__repr__, _asdict, __getnewargs__):

method.__qualname__ = f'{typename}.{method.__name__}'

# Build-up the class namespace dictionary

# and use type() to build the result class

class_namespace = {

'__doc__': f'{typename}({arg_list})',

'__slots__': (),

'_fields': field_names,

'_field_defaults': field_defaults,

# alternate spelling for backward compatibility

'_fields_defaults': field_defaults,

'__new__': __new__,

'_make': _make,

'_replace': _replace,

'__repr__': __repr__,

'_asdict': _asdict,

'__getnewargs__': __getnewargs__,

}

for index, name in enumerate(field_names):

doc = _sys.intern(f'Alias for field number {index}')

class_namespace[name] = _tuplegetter(index, doc)# 為我們定義的屬性字段賦值

result = type(typename, (tuple,), class_namespace)

# For pickling to work, the __module__ variable needs to be set to the frame

# where the named tuple is created. Bypass this step in environments where

# sys._getframe is not defined (Jython for example) or sys._getframe is not

# defined for arguments greater than 0 (IronPython), or where the user has

# specified a particular module.

if module is None:# 使用默認module名稱

try:

module = _sys._getframe(1).f_globals.get('__name__', '__main__')

except (AttributeError, ValueError):

pass

if module is not None:# 重新命名module名稱

result.__module__ = module

return result

使用Card = namedtuple('Card', ['rank', 'suit'])

在通過名字獲取值的方式上類似于class Card:

def __init__(self, rank, suit):

self.rank = rank

self.suit = suit

列表推導式[表達式 for 變量 in 列表]

[表達式 for 變量 in 列表 if 條件]

排序sort 是應用在 list 上的方法,sorted 可以對所有可迭代的對象進行排序操作。

list 的 sort 方法返回的是對已經存在的列表進行操作,而內建函數 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。

sortIn[1]:a = [3, 2, 1]

In[2]:a.sort()

In[3]:a

Out[3]:[1, 2, 3]

sorted

key 指定帶有單個參數的函數,用于從 iterable 的每個元素中提取用于比較的鍵 (例如 key=str.lower)。默認值為 None (直接比較元素)。In[1]:sorted([3, 2, 1])

Out[1]:[1, 2, 3]

魔方方法

__repr__和__str__repr:在repr()方法中使用。當沒有實現該方法的時候,打印實例可能為

str:在str()方法中使用,在print()方法中使用

當一個對象沒有__str__的時候會調用__repr__

自己定義__bool__方法

如果沒有定義的話,在執行bool(x)的時候默認會調用bool(x.__len__())

總結

以上是生活随笔為你收集整理的流畅的python第一章_《流畅的Python》第一章学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。