Python作为一种高级的动态编程语言,是出了名的容易使用。这促使它在最近几年里疯狂地流行和发展。使用的方便也伴随着误用的方便。我们把初学者在用Python写代码时可能犯的常见错误列在一起。
1.不必要的lambda表达式
在Python中,函数是一流的公民。这意味着你可以把它赋值给某个变量,在另一个函数调用中把它作为参数传递,如此等等。这对初学者或来自其他编程语言的开发者来说可能是反直觉的。
这种模式的一个常见例子是:
def request(self, method, **kwargs):
# ...
if method not in ("get", "post"):
req.get_method = lambda: method.upper()
# ...
推荐的写法是:
def request(self, method, **kwargs):
# ...
if method not in ("get", "post"):
req.get_method = method.upper
# ...
2.提起NotImplemented
这是一个类似的命名会让开发者感到困惑的例子。NotImplementedError 是一个异常类,当派生类需要覆盖一个方法时,应该被引发。NotImplemented 是一个常数,用来实现二进制运算符。当你引发NotImplemented ,就会引发一个TypeError 。
不正确:
class SitesManager(object):
def get_image_tracking_code(self):
raise NotImplemented
正确:
class SitesManager(object):
def get_image_tracking_code(self):
raise NotImplementedError
3.可变的默认参数
Python 中的默认参数在执行函数定义时被评估一次。这意味着表达式在定义函数时只被评估一次,并且在以后的每次调用中使用相同的值。因此,如果你在修改可变的默认参数--list,dict ,等等,它将被修改用于所有未来的调用。
不正确:
def add_item(new_item, items=[]):
items.append(new_item)
正确:
def add_item(new_item, items=None):
if items is None:
items = []
items.append(new_item)
4.使用assert 语句作为守护条件
由于assert 提供了一种简单的方法来检查一些条件并使执行失败,所以开发者使用它来检查有效性是非常普遍的。但是当Python解释器用-O (优化)标志调用时,assert 语句会从字节码中删除。因此,如果在生产代码中使用assert 语句进行面向用户的验证,那么这个块根本不会被执行--可能会打开一个安全漏洞。建议只在测试中使用assert 语句。
不正确:
assert re.match(VALID_ADDRESS_REGEXP, email) is not None
正确:
if not re.match(VALID_ADDRESS_REGEXP, email):
raise AssertionError
5.使用isinstance 来代替type
type 或isinstance 都可以用来检查 Python 中一个对象的类型。但是有一个重要的区别--isinstance 在解决对象的类型时照顾到了继承性,而type 则没有。所以有时使用isinstance 可能不是你想用的。看一下下面的例子:
def which_number_type(num):
if isinstance(num, int):
print('Integer')
else:
raise TypeError('Not an integer')
which_number(False) # prints 'Integer', which is incorrect
在这里,由于bool 是 Python 中int 的一个子类,isinstance(num, int) 也被评估为True ,这不是预期的行为。在这种特殊情况下,使用type 是正确的方法。在这里阅读更多关于这两种方法的行为差异。