Python是一门高级的动态编程语言,以易用着称。目前Python社区非常完备,近几年发展尤为迅猛。但易用性也有一些缺点,即易于误用。在这篇文章中,作者列举了初学者常犯的5个错误,希望能帮助初学者写出更正确、更漂亮的代码。1、变量默认参数Python中的默认参数会在函数定义执行时计算一次,也就是说表达式只在函数定义后执行一次,所以后续每次调用都可以使用默认值。如果我们将默认参数设置为变量,例如列表或字典,那么对于以后的所有调用,该参数始终是保留的和可变的。以下是错误的表达。如果我们第一次调用add_item添加“a”,items=[『a』]。当我们第二次调用add_item添加“b”时,由于定义中的items=[]只在初始化时运行一次,此时items=[『a』,『b』]。特别是当我们在调用add_item函数的时候没有传入任何参数,那么items仍然可以保留之前记忆的内容,相当于把之前的内容泄露给后面的调用。defadd_item(new_item,items=[]):items.append(new_item)正确的表达应该是这样的,当我们不传入items时,应该初始化为空列表:defadd_item(new_item,items=None):ifitemsisNone:items=[]items.append(new_item)2.使用assert语句作为保证条件由于assert语句很容易检查某些条件是否满足或者执行是否正确,所以开发者经常用它来检查有效性代码的某一部分。但是当使用-O(优化)标志调用Python解释器时,断言语句将从字节码中删除。所以,如果assert语句在用户认证的产品代码中,根本不会被执行,因为它可能会造成一些安全漏洞。因此,开发人员应该只在测试中使用assert语句。错误的例子如下:assertre.match(VALID_ADDRESS_REGEXP,email)isnotNone正确的代码应该改为:ifnotre.match(VALID_ADDRESS_REGEXP,email):raiseAssertionError3。使用isinstance而不是typetype并且isinstance可以检查对象是什么类。但是它们之间有一个非常重要的区别。isinstance在解析目标类型时,会关注继承关系,而type则不会。由于这种差异,isinstance有时并不是我们认为的那样。例如以下情况:defwhich_number_type(num):ifisinstance(num,int):print('Integer')else:raiseTypeError('Notaninteger')which_number(False)#prints'Integer',这是不正确的,因为布尔变量在Python中int的子类isinstance(num,int)也会产生True,这不是我们想要的。在某些类别中,使用类型可能更正确。4.不必要的lambda表达式函数是Python中最常用的结构。我们可以将一个函数赋值给一个变量,并将变量作为参数传递给另一个函数,这也是函数的常见用法。但是对于初学者或者了解其他编程语言的开发者来说,这种传递方式是非常反直觉的。一个更常见的模式可以表示为:defrequest(self,method,**kwargs):#...ifmethodnotin("get","post"):req.get_method=lambda:method.upper()使用匿名函数上面的lambda的方式,最好改成下面这样:defrequest(self,method,**kwargs):#...ifmethodnotin("get","post"):req.get_method=method.upper#...5。NotImplementedError这种命名会使开发人员感到困惑。NotImplementedError是派生类需要重写方法时Python应该触发的异常类。而NotImplemented是一个常量,用来实现二元运算。当我们触发NotImplemented时,Python会给出“TypeError”错误。错误示例:classSitesManager(object):defget_image_tracking_code(self):raiseNotImplemented正确的表达方式应该是:classSitesManager(object):defget_image_tracking_code(self):raiseNotImplementedError原文链接:https://deepsource.io/blog/python-common-mistakes/【本文为栏目组织《机器之心》,微信公众号《机器之心(id:almosthuman2014)》原创翻译】点此查看作者更多好文
