编写高质量代码-改善python的91个建议-基本语法-笔记

编写高质量代码-改善python的91个建议-基本语法

  • 有节制地使用from XXX import *
  • 优先使用absolute import.
  • 区分可变对象和不可变对象.
  • 区分staticmethod和classmethod的适用场景.
  • 记住函数传参不是传值也不是传引用
  • 注意finally的陷阱
  • 理解None,正确判断对象是否为空
  • 注意函数的默认参数
  • 正确理解str和repr的区别
  • 注意函数的返回值
  • 字符串的基本使用。

区分可变对象和不可变对象

根据其值是否要变可以区分可变对象和不可变对象. 也可通过内建函数id来查出.

如 字符串是不可变对象


s = 'hello'
s[2] = 'a'
TypeError: 'str' object does not support item assignment

import array
a = array.array('c', s)
a[2] = 'a'
a.tostring()

小结

这种错,系统能检查出来。

区分staticmethod和classmethod的适用场景.

staticmethod和classmethod的区别是classmethod多传入了一个cls, 这就是这个方法要对cls的属性进行一定的操作, 一般要类的继承和属性时,就可能用到

例子:


class Fruit(object):
    total = 0
    @classmethod
    def print_total(cls):
        print cls.total

    @classmethod
    def set(cls, value):
        cls.total = value

class Apple(Fruit):
    pass

class Orange(Fruit):
    pass

a = Apple()
a.set(200)
b = Orange()
b.set(300)

a.print_total()
b.print_total()

# 启发
@classmethod
def Init_Product(cls, product_info):
    area, category, batch = map(int, product_info)
    fruit = cls(area, category, batch)
    return fruit

记住函数传参不是传值也不是传引用

正确叫法是传对象,对象一旦建立,不能取代为其他对象,只能修改对象的属性。

注意finally的陷阱

把return break 放在finally会出现错误

理解None, 正确判断对象为空.

根据python 默认为空的做法,空列表,空字符串,空字典,空元组,任何数值类型为0. 在此不使用len来判断,是因为这样兼容性不太好.

注意 空不等于为None

例子:

lst = []

if lst is None:
    print "never exec this!"

# 正确的做法

lst = []

if not lst:
    print 'lst is empty'


注意函数的默认参数

容易出错的例子,本来想要新对象,结果不这旧对象了.


def make_list(count, lst=[]):
    for i in range(count):
        lst.append(i)
    return lst

>>> make_list(2)

## 正确理解str和repr的区别 总结: repr 是面向开发者,str是面向基本用户.要求定义__repr__能通过eval还原.


In [1]: import datetime

In [2]: a = datetime.datetime.now()

In [3]: a
Out[3]: datetime.datetime(2015, 11, 9, 18, 26, 23, 936016)

In [4]: str(a)
Out[4]: '2015-11-09 18:26:23.936016'

In [5]: repr(a)
Out[5]: 'datetime.datetime(2015, 11, 9, 18, 26, 23, 936016)'


注意函数的返回值

当没有显式返回时,结果是为None,不会报错。


In [1]: lst = [1, 2, 3]

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

In [3]: lst = lst.append(4)

In [4]: lst


这样默默地改变了lst,如不知道,在这种情况下,我只能说对于不懂的要多多测试。

字符串的基本使用

  • 查找
  • 连接
  • 分割
  • 判断

查找

只要找到是否包含的话, in 和 not in比较直观 find 和 index等等返回起始位置,但失败时表现形式不同, find 是返回-1, index是ValeError异常.

判断是否包含子串是不推荐使用find index方法,推荐使用in 和not in.

连接

多行连接


s = "hello" + "world" + "lsl" + \
"xxx"
# 表现得有点难看
s = "".join(
"hello"
"world"
"lsl"
)
s = (
"hello"
"world"
"lsl"
)
# 经常用到的是

sql = ("select *"
"from user"
)

# 为什么不使用
"""
"""
因为有\n了


值得注意的问题

  1. 注意在python 中字符串的判断分法,因为basestring是str和unicode的基类,因此 isinstrace(s, basestring)

小说basestring basestring是str和unicode的超类(父类),也是抽象类,因此不能被调用和实例化,但可以被用来判断一个对象是否为str或者unicode的实例


In [1]: basestring()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-c25c0a949701> in <module>()
----> 1 basestring()

TypeError: The basestring type cannot be instantiated

分割

partition,

左边,sep,右边 split 是接照sep,分割下去.

注意 split()和split(“ “)结果是不同的

参考

编写高质量代码-发送python91的建议.

Loading Disqus comments...
Table of Contents