Skip to content

rockyxiashilong/example-code

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fluent Python: example code .. _Fluent Python: http://shop.oreilly.com/product/0636920032519.do

1.从upstream(远程仓库) fork 一个个人仓库 例如:https://github.com/rockyxiashilong/WeEvent.git

2.本地 git clone https://github.com/rockyxiashilong/WeEvent.git
$ git remote -v //克隆成功后,查看远程仓库,看到如下个人仓库 origin https://github.com/rockyxiashilong/WeEvent.git (fetch) origin https://github.com/rockyxiashilong/WeEvent.git (push)
3.添加远程仓库 git remote add upstream https://github.com/WeBankFinTech/WeEvent.git
$ git remote -v origin https://github.com/rockyxiashilong/WeEvent.git (fetch) origin https://github.com/rockyxiashilong/WeEvent.git (push) upstream https://github.com/WeBankFinTech/WeEvent.git (fetch) upstream https://github.com/WeBankFinTech/WeEvent.git (push)

4.更新远程仓库 git fetch upstream 5.然后合入本地master git rebase

git log -3 查看最新三次提交,看看本地仓库是不是已经是最新的代码了

6.创建分支 git checkout -b add_testcase

7.修改代码后,提交本地分支到个人远程仓,然后提交pr请求合入主仓库 git push --set-upstream origin add_testcase

学习笔记 第1-2章 1.一致性的感念理解:python中的一切都是对象,对象的基类是object,提供了一些包含类似__len__de 用法,当用户调用len(obj)时,其实调用的是obj.__len_()方法 主要包含的pythonic方法,算术运算符、__getitem__;__setitem__支持索引和切片;__get__;__set__用于属性管理;__init__、__new__用于进行类的初始化管理

第3章 容器类型 2.生成器和迭代器[]{}()中不需要用转义符进行换行,列表推导式生成的是一个列表,生成器生成的是一个生成器对象,更省内存,需要的时候才生成元素,都实现了__iter__方法,可迭代对象都支持拆包操作,即支持for循环拆包和赋值拆包

3.列表按数据是否连续存放可以分成扁平化列表和非扁平化列表,例如list、tuple都是非扁平化列表,str和byte都是扁平化列表;依据是否支持__setitem__,可以分成可变列表(list、dict)和不可变(tuple、str)

4.还可以用 * 运算符把一个可迭代对象拆开作为函数的参数page64+:
>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t)
(2, 4)
>>> quotient, remainder = divmod(*t)
>>> quotient, remainder
(2, 4)

5.序列支持切片操作,支持切片赋值操作,切片赋值操作的右值必须是一个可以迭代的对象,序列操作的+、*操作符都会产生一个新的序列对象, += 、*= 操作才会 就地返回。

>>> l = list(range(10))
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[2:5] = [20, 30]
>>> l
[0, 1, 20, 30, 5, 6, 7, 8, 9]
>>> del l[5:7]
>>> l
[0, 1, 20, 30, 5, 8, 9]
>>>
l[3::2] = [11, 22]
>>> l
[0, 1, 20, 11, 5, 22, 9]
>>> l[2:5] = 100  ➊
Traceback (most recent call last):  File "<stdin>", line 1, in <module> TypeError: can only assign an iterable
>>> l[2:5] = [100]
>>> l
[0, 1, 100, 22, 9]

6.如果一个函数或者方法对对象进行的是就地改动,那它就应该返回 None,好让调用者知道传入的参数发生了变动,而且并未产生新的对象

7.collections.abc 模块中有 Mapping 和 MutableMapping 这两个 抽象基类,定义了字段的接口

8.字典推导{}
>>> b = {key:value for key,value in (("one",1),("two",2))}
>>> b
{'one': 1, 'two': 2}

9.dict、collections.defaultdict和 collections.OrderedDict

10.d[key] 和d.get(key)的主要区别 前者key不存在会返回KeyError,后者会返回default或者None

11.__missing__ 方法,当__getitem__方法找不到key时,返回会调用该方法再进行一次处理

12.collections.OrderedDict 有序字典 collections.ChainMap 多个字段的组合 collections.Counter 计数字典,初始化时传入一个可迭代对象, 构造出一个key 为迭代对象,值为对应key出现次数的字典 colllections.UserDict 抽象类,用于继承和实现

13、不可变对象MappingProxyTyp
>>> from types import MappingProxyType
>>> d = {1:'A'}
>>> d_proxy = MappingProxyType(d)
>>> d_proxy mappingproxy({1: 'A'}
14.set对象可以理解为去重的可迭代对象,可以直接字面值初始化、也可以用一个可以迭代的对象进行初始化。
>>> a = {1,2,3,4}
>>> a
set([1, 2, 3, 4])
>>> b = set([1,2,3,4,5,1,2,3])
>>> b
set([1, 2, 3, 4, 5])

15.dict对象为啥可以实现O(1)算法的数据查找,采用的是散列算法,d[key]时先算出hash(key),然后找到散列对象后,会调用__eq__方法,进行比较,看是否相等。

第四章 文本和字节序列
---人类使用文本,计算机使用字节序列

16 bytes array.arrary struct utf-8 utf-16 编码格式和解码格式需要保持一致,其中windows中文的默认编码格式是产cp1252,unix编码格式utf-8,windows读写文件时,最好指定编码集,防止出现乱码。

第五章

1.map filter 高阶函数都有替代方案,可以用列表生成式来替代;高阶函数是指参数可以为函数对象或者返回值为函数对象的函数

2.匿名函数 lambda,不好阅读的lambda不建议使用,只是语法糖,完全可以用def函数来处理

3.callable() 一般而言,实例不是可调用对象,除非其实现了__call__方法。 4.函数也是对象,比普通对象多一些属性 __defaults__(返回参数的默认值) __code__ __name__函数名,注意,装饰器会破坏函数的上述对应信息

第6章 使用一等函数实现设计模式 策略模式和命令模式 可以用函数来替代,而不需要使用抽象类来实现

第12章 类和多重继承 12.1 cls.__mro__会显示类的解析顺序,类调用方法时,若无指定用哪个类的方法,会按照解析顺序进行调用。D(B,C)解析顺序中,B再前,C再后,遇到B/C中有同名的函数时,当D类实例调用是会先调用B中的方法。

12.2 设计方法

1.把接口和实现继承区分开 使用多重继承时,一定要明确一开始为什么创建子类。主要原因可 能有: 继承接口,创建子类型,实现“是什么”关系 继承实现,通过重用避免代码重复 其实这两条经常同时出现,不过只要可能,一定要明确意图。通过 继承重用代码是实现细节,通常可以换用组合和委托模式。而接口 继承则是框架的支柱

2.使用抽象基类显式表示接口
现代的 Python 中,如果类的作用是定义接口,应该明确把它定义为 抽象基类。 Python 3.4 及以上的版本中,我们要创建 abc.ABC 或其 他抽象基类的子类(如果想支持较旧的 Python 版本,参见 11.7.1 节)
3.通过混入重用代码
如果一个类的作用是为多个不相关的子类提供方法实现,从而实现重用,但不体现“是什么”关系,应该把那个类明确地定义为混入类(mixin class)。 从概念上讲,混入不定义新类型,只是打包方法,便于重用。 混入类绝对不能实例化,而且具体类不能只继承混入类。 混入类应该提供某方面的特定行为,只实现少量关系非常紧 密的方法

4.在名称中明确指明混入 因为在 Python 中没有把类声明为混入的正规方式,所以强烈推荐在 名称中加入 ...Mixin 后缀。 Tkinter 没有采纳这个建议,如果采 纳的话,XView 会变成 XViewMixin,Pack 会变成 PackMixin,图 12-3 中所有使用 «mixin» 标记的类都应该这么 做。

5.抽象基类可以作为混入,反过来则不成立
抽象基类可以实现具体方法,因此也可以作为混入使用。不过,抽 象基类会定义类型,而混入做不到。此外,抽象基类可以作为其他 类的唯一基类,而混入决不能作为唯一的超类,除非继承另一个更 具体的混入——真实的代码很少这样做。

抽象基类有个局限是混入没有的:抽象基类中实现的具体方法只能 与抽象基类及其超类中的方法协作。这表明,抽象基类中的具体方 法只是一种便利措施,因为这些方法所做的一切,用户调用抽象基 类中的其他方法也能做到。

  1. 不要子类化多个具体类
具体类可以没有,或最多只有一个具体超类。 也就是说,具体类 的超类中除了这一个具体超类之外,其余的都是抽象基类或混入。 例如,在下述代码中,如果 Alpha 是具体类,那么 Beta 和 Gamma 必须是抽象基类或混入:

07. 为用户提供聚合类 如果抽象基类或混入的组合对客户代码非常有用,那就提供一个 类,使用易于理解的方式把它们结合起来。Grady Booch 把这种类 称为聚合类(aggregate class)。 例如,下面是 tkinter.Widget 类的完整代码 (https://hg.python.org/cpython/file/3.4/Lib/tkinter/__init__.py#l2141): class Widget(BaseWidget, Pack, Place, Grid): """Internal class.Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid."""

pass

Widget 类的定义体是空的,但是这个类提供了有用的服务:把四 个超类结合在一起,这样需要创建新小组件的用户无需记住全部混 入,也不用担心声明 class 语句时有没有遵守特定的顺序。 Django 中的 ListView 类是更好的例子,稍后在 12.5 节讨论

08. “优先使用对象组合,而不是类继承” 这句话引自《设计模式:可复用面向对象软件的基础》一书, 这 是我能提供的最佳建议。熟悉继承之后,就太容易过度使用它了。 出于对秩序的诉求,我们喜欢按整洁的层次结构放置物品,程序员 更是乐此不疲。 然而,优先使用组合能让设计更灵活。例如,对 tkinter.Widget 类来说,它可以不从全部几何管理器中继承方 法,而是在小组件实例中维护一个几何管理器引用,然后通过它调 用方法。毕竟,小组件“不是”几何管理器,但是可以通过委托使用 相关的服务。这样,我们可以放心添加新的几何管理器,不必担心 会触动小组件类的层次结构,也不必担心名称冲突。即便是单继 承,这个原则也能提升灵活性,因为子类化是一种紧耦合,而且较 高的继承树容易倒。 组合和委托可以代替混入,把行为提供给不同的类,但是不能取代 接口继承去定义类型层次结构

About

Example code for the book Fluent Python

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 98.2%
  • Other 1.8%