《编写高质量代码 改善python程序的91个建议》读书笔记

前言: python 一切皆对象,此为前提。

一、关于函数:不要在函数中定义可变对象为默认值,使用异常替换返回错误,保证通过单元测试。python函数传递的是对象的引用。在类的初始化方法里,参数的默认值应该为None,因为默认参数在函数被调用时候仅仅被评估一次。

二、编码。 最开始使用ASCII使用一个字节(8bit)只能表示128个字符;unicode 实现了从数字代码到不同语言字符集之间的映射,从而跨平台、跨语言的要求。但是在实际传输过程中,为了节省内存,实现Unicode 的过程叫 Unicode格式转换(transformaition format),简称UTF。其中最常见的UTF-8对不同范围的字符使用不同长度的编码:0x00- 0x7F的字符的UTF-8编码与ASCII编码完全相同。UTF-8的最大长度为4个字节(32bit)。

decode("utf-8")  #将其他编码对应的字符串解码成Unicode
encode("utf-8")  #将Unicode编码转换为另一种编码。

三、import VS from ... import x : from +import 会带来命名空间冲突。

四、++i 在python里等价于+(+i) 。+表示正号。

五、使用with open() as f  来进行文件读写。文件实现了上下文协议,任何实现了上下文协议的对象都可以成为上下文管理器。有_enter_() 和_exti()_两个方法

__enter__():在使用with语句时调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定

__exit__():会话管理器在代码块执行完成好后调用,在with语句完成时,对象销毁之前调用

六、异常处理:1. 尽量只在可能抛出异常的语句前加入try。谨慎使用单独的except 处理所有异常,因为会掩盖异常到底在哪里,只知道发生了异常。注意异常捕获的顺序,在合适的层次处理异常。2. 如果finally 后面的语句里有return 和break, 同时try捕获的错误在except中找不到对应的异常处理,那么在执行完finally后,异常便不能被抛出,导致异常丢失。同时finally里面的return语句是最先被执行的,会覆盖前面的return语句。因为不能再finally写return。

七、字符串连接:优先使用join 申请一次内存 时间复杂度O(n) 。 而 + 连接多个字符串的时候,每个+申请一次内存,复杂度O(n^2)

八、静态方法和类方法:子类实现某些功能的时候使用类方法可以避免代码重写带来的冗余。

扫描二维码关注公众号,回复: 4693189 查看本文章

九、字符串切分: split() 无视所有空格。 split(' ')会保留空字符串。capwords(s):去除两端空格,并把连续空白字符用一个空格代替。

十、排序。 sorted()    

textbook = {'张三':'7705','李四':'9345'}
from operator import itemgetter  # 获取第几个域的值
sorted_pb = sorted(textbook.items(),key=itemgetter(1))
print(sorted_pb)

十一、深拷贝和浅拷贝。深拷贝:包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变。

十二、计数

#Counter类是字典类的子类,是一个容器对象,用来统计散列对象。
from collections import Counter
some_data = ['a','2',2,4,5,'2','b',4,7,'a',5,'d','a','z']
print(Counter(some_data))

十三、traceback 获取异常发生时候栈的信息

十四、maxin。 与其他静态语言不同, Python语言中的基类在运行中可以动态改变。 所以当我们向其中增加新的基类时, 这个类就拥有了新的方法, 也就是所谓的混入(mixin) 。 这种动态性的好处在于代码获得了更丰富的扩展功能。 想象一下, 你之前写好的代码并不需要个性, 只要后期为它增加基类, 就能够增强功能(或替换原有行为) , 这多么方便! 值得进一步探索的是, 利用反射技术, 甚至不需要修改代码。

十五、state模块

通过引入@ensure_signin,可以代替if判断语句
def ensure_signin(func):
    def _func(self, *a, **kw):
        if not self._signin:
            raise NeedSignin()
        return func(self, *a, **kw)
    return _func
@ensure_signin
def do_sth(self, *a, **kw):

十六、 __init()__ 不是构造方法!! __new__()才是构造方法!!

·__new__()方法一般需要返回类的对象, 当返回类的对象时将会自动调用__init__()方法进行初始化, 如果没有对象返回, 则__init__()方法不会被调用。 __init__()方法不需要显式返回, 默认为None,否则会在运行时抛出TypeError。

十七、命名空间 Python中所有的变量名都是在赋值的时候生成的, 而对任何变量名的创建、 查找或者改变都会在命名空间(namespace) 中进行。

十八、 描述符     2. __getattribute__()总会被调用, 而__getattr__()只有在__getattribute__()中引发异常的情况下才会被调
用  3. 数据描述符: 如果一个对象同时定义了__get__()和__set__()方法, 则称为数据描述符, 如果仅定义了__get__()方法, 则称为非数据描述符 4。 很多地方将property称为函数, 我个人认为这是不恰当的, 它实际上是一种实现了__get__()、 __set__()方法的类, 用户也可以根据自己的需要定义个性化的property。property 是数据描述符。
十九、利用操作符重载实现中缀语法  pipe
 

猜你喜欢

转载自blog.csdn.net/qq_34333481/article/details/85260694