编写高质量代码-改善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了
值得注意的问题
- 注意在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的建议.