梳理总结Python开发中需要摒弃的18个坏习惯


Posted in Python onJanuary 22, 2022

废话不多说,我们开始学习吧!

1、拼接字符串用 + 号

坏的做法:

def manual_str_formatting(name, subscribers):
    if subscribers > 100000:
        print("Wow " + name + "! you have " + str(subscribers) + " subscribers!")
    else:
        print("Lol " + name + " that's not many subs")

好的做法是使用 f-string,而且效率会更高:

def manual_str_formatting(name, subscribers):
    # better
    if subscribers > 100000:
        print(f"Wow {name}! you have {subscribers} subscribers!")
    else:
        print(f"Lol {name} that's not many subs")

2、使用 finaly 而不是上下文管理器

坏的做法:

def finally_instead_of_context_manager(host, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((host, port))
        s.sendall(b'Hello, world')
    finally:
        s.close()

好的做法是使用上下文管理器,即使发生异常,也会关闭 socket::

def finally_instead_of_context_manager(host, port):
    # close even if exception
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((host, port))
        s.sendall(b'Hello, world')

3、尝试手动关闭文件

坏的做法:

def manually_calling_close_on_a_file(filename):
    f = open(filename, "w")
    f.write("hello!\n")
    f.close()

好的做法是使用上下文管理器,即使发生异常,也会自动关闭文件,凡是有上下文管理器的,都应该首先采用:

def manually_calling_close_on_a_file(filename):
    with open(filename) as f:
        f.write("hello!\n")
    # close automatic, even if exception

4、except 后面什么也不写

坏的做法:

def bare_except():
    while True:
        try:
            s = input("Input a number: ")
            x = int(s)
            break
        except:  # oops! can't CTRL-C to exit
            print("Not a number, try again")

这样会捕捉所有异常,导致按下 CTRL-C 程序都不会终止,好的做法是

def bare_except():
    while True:
        try:
            s = input("Input a number: ")
            x = int(s)
            break
        except Exception:  # 比这更好的是用 ValueError
            print("Not a number, try again")

5、函数参数使用可变对象

如果函数参数使用可变对象,那么下次调用时可能会产生非预期结果,坏的做法

def mutable_default_arguments():
    def append(n, l=[]):
        l.append(n)
        return l

    l1 = append(0)  # [0]
    l2 = append(1)  # [0, 1]

好的做法:

def mutable_default_arguments():

    def append(n, l=None):
        if l is None:
            l = []
        l.append(n)
        return l

    l1 = append(0)  # [0]
    l2 = append(1)  # [1]

6、从不用推导式

坏的做法

squares = {}
for i in range(10):
    squares[i] = i * i

好的做法

odd_squares = {i: i * i for i in range(10)}

7、推导式用的上瘾

推导式虽然好用,但是不可以牺牲可读性,坏的做法

c = [
    sum(a[n * i + k] * b[n * k + j] for k in range(n))
    for i in range(n)
    for j in range(n)
]

好的做法:

c = []
for i in range(n):
    for j in range(n):
        ij_entry = sum(a[n * i + k] * b[n * k + j] for k in range(n))
        c.append(ij_entry)

8、检查类型是否一致用 ==

坏的做法

def checking_type_equality():
    Point = namedtuple('Point', ['x', 'y'])
    p = Point(1, 2)

    if type(p) == tuple:
        print("it's a tuple")
    else:
        print("it's not a tuple")

好的做法

def checking_type_equality():
    Point = namedtuple('Point', ['x', 'y'])
    p = Point(1, 2)

    # probably meant to check if is instance of tuple
    if isinstance(p, tuple):
        print("it's a tuple")
    else:
        print("it's not a tuple")

9、用 == 判断是否单例

坏的做法

def equality_for_singletons(x):
    if x == None:
        pass

    if x == True:
        pass

    if x == False:
        pass

好的做法

def equality_for_singletons(x):
    # better
    if x is None:
        pass

    if x is True:
        pass

    if x is False:
        pass

10、判断一个变量用 bool(x)

坏的做法

def checking_bool_or_len(x):
    if bool(x):
        pass

    if len(x) != 0:
        pass

好的做法

def checking_bool_or_len(x):
    # usually equivalent to
    if x:
        pass

11、使用类 C 风格的 for 循环

坏的做法

def range_len_pattern():
    a = [1, 2, 3]
    for i in range(len(a)):
        v = a[i]
        ...
    b = [4, 5, 6]
    for i in range(len(b)):
        av = a[i]
        bv = b[i]
        ...

好的做法

def range_len_pattern():
    a = [1, 2, 3]
    # instead
    for v in a:
        ...

    # or if you wanted the index
    for i, v in enumerate(a):
        ...

    # instead use zip
    for av, bv in zip(a, b):
        ...

12、不实用 dict.items

坏的做法

def not_using_dict_items():
    d = {"a": 1, "b": 2, "c": 3}
    for key in d:
        val = d[key]
        ...

好的做法

def not_using_dict_items():
    d = {"a": 1, "b": 2, "c": 3}
    for key, val in d.items():
        ...

13、解包元组使用索引

坏的做法

mytuple = 1, 2
x = mytuple[0]
y = mytuple[1]

好的做法

mytuple = 1, 2
x, y = mytuple

14、使用 time.time() 统计耗时

坏的做法

def timing_with_time():
    start = time.time()
    time.sleep(1)
    end = time.time()
    print(end - start)

好的做法是使用 time.perf_counter(),更精确:

def timing_with_time():
   # more accurate
    start = time.perf_counter()
    time.sleep(1)
    end = time.perf_counter()
    print(end - start)

15、记录日志使用 print 而不是 logging

坏的做法

def print_vs_logging():
    print("debug info")
    print("just some info")
    print("bad error")

好的做法

def print_vs_logging():
    # versus
    # in main
    level = logging.DEBUG
    fmt = '[%(levelname)s] %(asctime)s - %(message)s'
    logging.basicConfig(level=level, format=fmt)

    # wherever
    logging.debug("debug info")
    logging.info("just some info")
    logging.error("uh oh :(")

16、调用外部命令时使用 shell=True

坏的做法

subprocess.run(["ls -l"], capture_output=True, shell=True)

如果 shell=True,则将 ls -l 传递给/bin/sh(shell) 而不是 Unix 上的 ls 程序,会导致 subprocess 产生一个中间 shell 进程, 换句话说,使用中间 shell 意味着在命令运行之前,命令字符串中的变量、glob 模式和其他特殊的 shell 功能都会被预处理。比如,$HOME 会在在执行 echo 命令之前被处理处理。

好的做法是拒绝从 shell 执行:

subprocess.run(["ls", "-l"], capture_output=True)

17、从不尝试使用 numpy

坏的做法

def not_using_numpy_pandas():
    x = list(range(100))
    y = list(range(100))
    s = [a + b for a, b in zip(x, y)]

好的做法:

import numpy as np
def not_using_numpy_pandas():
    # 性能更快
    x = np.arange(100)
    y = np.arange(100)
    s = x + y

18、喜欢 import *

坏的做法

from itertools import *

count()

这样的话,没有人直到这个脚本到底有多数变量, 好的做法:

from mypackage.nearby_module import awesome_function

def main():
    awesome_function()

if __name__ == '__main__':
    main()

到此这篇关于梳理总结Python开发中需要摒弃的18个坏习惯的文章就介绍到这了,更多相关Python 坏习惯内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python使用Tkinter显示网络图片的方法
Apr 24 Python
Python 通过pip安装Django详细介绍
Apr 28 Python
Python中单、双下划线的区别总结
Dec 01 Python
windows下安装Python的XlsxWriter模块方法
May 03 Python
Python 从一个文件中调用另一个文件的类方法
Jan 10 Python
pyqt5实现俄罗斯方块游戏
Jan 11 Python
python rsync服务器之间文件夹同步脚本
Aug 29 Python
python 遍历pd.Series的index和value
Nov 26 Python
python实现12306登录并保存cookie的方法示例
Dec 17 Python
Python动态声明变量赋值代码实例
Dec 30 Python
TensorFlow MNIST手写数据集的实现方法
Feb 05 Python
浅谈Keras中shuffle和validation_split的顺序
Jun 19 Python
Pandas搭配lambda组合使用详解
Jan 22 #Python
Python中的tkinter库简单案例详解
Jan 22 #Python
解析python中的jsonpath 提取器
Jan 18 #Python
Python中如何处理常见报错
Jan 18 #Python
Python机器学习应用之工业蒸汽数据分析篇详解
用Python可视化新冠疫情数据
Python机器学习应用之基于线性判别模型的分类篇详解
You might like
php调用方法mssql_fetch_row、mssql_fetch_array、mssql_fetch_assoc和mssql_fetch_objcect读取数据的区别
2012/08/08 PHP
详解PHP+AJAX无刷新分页实现方法
2015/11/03 PHP
PHP简单实现二维数组赋值与遍历功能示例
2017/10/19 PHP
jQuery把表单元素变为json对象
2013/11/06 Javascript
根据表格中的某一列进行排序的javascript代码
2013/11/29 Javascript
JavaScript对象的property属性详解
2014/04/01 Javascript
JavaScript中的DSL元编程介绍
2015/03/15 Javascript
在JavaScript中操作时间之getYear()方法的使用教程
2015/06/11 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
2016/05/30 Javascript
Angular 页面跳转时传参问题
2016/08/01 Javascript
防止Node.js中错误导致进程阻塞的办法
2016/08/11 Javascript
Javascript Function.prototype.bind详细分析
2016/12/29 Javascript
深入理解Angularjs向指令传递数据双向绑定机制
2016/12/31 Javascript
nodejs处理图片的中间件node-images详解
2017/05/08 NodeJs
JS与CSS3实现图片响应鼠标移动放大效果示例
2018/05/04 Javascript
nodeJS服务器的创建和重新启动的实现方法
2018/05/12 NodeJs
详解js实时获取并显示当前时间的方法
2019/05/10 Javascript
JavaScript实现点击图片换背景
2020/11/20 Javascript
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
盘点提高 Python 代码效率的方法
2014/07/03 Python
Python使用QRCode模块生成二维码实例详解
2017/06/14 Python
Python3实现的旋转矩阵图像算法示例
2019/04/03 Python
python 计算方位角实例(根据两点的坐标计算)
2020/01/17 Python
python识别验证码图片实例详解
2020/02/17 Python
python3 简单实现组合设计模式
2020/07/02 Python
PIP和conda 更换国内安装源的方法步骤
2020/09/21 Python
python 获取计算机的网卡信息
2021/02/18 Python
美国在线奢侈品寄售商店:Luxury Garage Sale
2018/08/19 全球购物
Armor Lux法国官方网站:水手服装、成衣和内衣
2020/05/26 全球购物
妇产医师自荐信
2014/01/29 职场文书
会计演讲稿范文
2014/05/23 职场文书
信电学院毕业生自荐书
2014/05/24 职场文书
领导干部学习“三严三实”思想汇报
2014/09/15 职场文书
某药房的新员工入职告知书!
2019/07/15 职场文书
创业计划书之物流运送
2019/09/17 职场文书
基于nginx实现上游服务器动态自动上下线无需reload的实现方法
2021/03/31 Servers