Python 中的有几种反模式?python常见反模式分享!

2021-08-25 15:23:00 浏览数 (2419)

1. 不with用于打开文件

当您打开一个没有该with语句的文件时,您需要记住close()在完成处理后通过显式调用关闭文件。即使明确关闭资源,在实际释放资源之前也有可能发生异常。这可能会导致不一致,或导致文件损坏。打开文件通过with实现上下文管理器协议,当执行在with块之外时释放资源。

不好的做法:

Python:

new_file = open('some-file.txt', 'r')

# do something exciting

new_file.close()

良好做法:

Python:

with open('some-file.txt', 'r') as fd:

 data = fd.read()

 # do something exciting

2.使用list/ dict/set理解不必要

内置类似功能all,any,enumerate,iter,itertools.cycle和itertools.accumulate可以直接与发电机表达工作。他们不需要理解。

除了他们,all()并any()在Python也支持短路,但如果使用理解这种行为将丢失。这会影响性能。

不好的做法:

Python:

...
comma_seperated_names = ','.join([name for name in my_fav_superheroes])

良好做法:

Python:

...
comma_seperated_numbers = ','.join(name for name in my_fav_superheroes)

3. 不必要地使用发电机

没有必要在对 的调用中使用生成器表达式list,dict或者set因为对于这些类型中的每一种都有理解。代替使用list/ dict/set周围生成器表达式,它们可以被写为它们各自的理解。

不好的做法:

Python:

squares = dict((i,i**2) for i in range(1,10))

良好做法:

Python:

squares = {i: i**2 for i in range(1,10)}

4. 在函数调用中返回多个对象类型

在函数中具有不一致的返回类型会使代码混乱且难以理解,并可能导致难以解决的错误。如果函数应该返回给定类型(例如整数常量、列表、元组),但也可以返回其他类型,则该函数的调用者将始终需要检查返回值的类型。建议从函数中只返回一种类型的对象。

如果在某些失败的情况下需要返回空的东西,建议引发一个可以干净地捕获的异常。

不好的做法:

Python:

def get_person_age(name):
    person = db.get_person(name)
    if person:
        return person.age  # returns an int

    # returns None if person not found

良好做法:

Python:

def get_person_age(name):
    person = db.get_person(name)
    if not person:
        raise Exception(f'No person found with name {name}')
    return person.age  # guaranteed to return int every time

5. 不使用get()从字典中返回默认值

这种反模式会影响代码的可读性。我们经常看到代码创建一个变量,为其分配一个默认值,然后在字典中查找某个键。如果键存在,则键的值被分配给变量的值。这样做虽然没有什么问题,但由于它查询了两次字典,因此冗长且效率低下,而使用get()字典的方法可以轻松完成。

不好的做法:

Python:

currency_map = {'usd': 'US Dollar'}

if 'inr' in currency_map:
  indian_currency_name = currency_map['inr']
else:
  indian_currency_name = 'undefined'

良好做法:

Python:

currency_map = {'usd': 'US Dollar'}
indian_currency_name = currency_map.get('inr', 'undefined')

6. 不使用items()迭代字典

items字典上的方法返回一个带有键值元组的可迭代对象,可以在for循环中解包。这种方法是惯用的,因此值得推荐。

不好的做法:

Python:

for code in country_map:
    name = country_map[code]
    # do something with name

良好做法:

Python:

for code, name in country_map.items():
    # do something with name
    pass

7.不使用文字语法来初始化空list/ dict/tuple

通过调用初始化空字典dict()比使用空字面值要慢,因为名称dict必须在全局范围内查找,以防它被重新绑定。其他两种类型也是如此 -list()和tuple().

不好的做法:

Python:

my_evans = list()
# Add something to this empty list

良好做法:

Python:

my_evans = []
# Add something to this empty list

8. 在生产代码中推送调试器

我们大多数人至少做过一次——在调试代码时,可能会发生在你发现错误后推送代码但忘记删除调试器的情况。这很关键,可能会影响代码的行为。强烈建议在签入之前审核代码以删除调试器的调用。

使用 Python 分析器,您可以在代码库中的所有这些反模式投入生产之前检测它们。