Python中常见的反模式

110 阅读4分钟

Python中常见的反模式

通过学习这些常见的反模式来改进和简化你的代码,这将为你节省时间和精力。包括好的和坏的做法的例子。

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 Comprehension

all,any,enumerate,iter,itertools.cycleitertools.accumulate 这样的内置函数可以直接与生成器表达式一起工作。它们不需要理解。

除了它们之外,Python 中的all()any() 也支持短路,但是如果使用了理解,这种行为就会消失。这影响了性能。

不好的做法:

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,dictset 的过程中使用生成器表达式是不必要的,因为这些类型都有相应的理解力。不要在生成器表达式周围使用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分析器,你可以在代码库中的所有这些反模式在它们落入生产之前就被发现。

编码愉快

经Srijan Saurav许可发表于DZone点击这里查看原文。

DZone贡献者所表达的观点属于他们自己。