论Python代码风格与编程习惯的重要性

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 实现高内聚,低耦合、结构清晰不臃肿、可读性高、数据冗余性低、高复用、易扩展的代码,并非易事。上到设计模式,下到某个类、方法、函数的构造。在这里我分享一下我自己的代码设计、编写风格,让我们互相学习。## Python代码风格

引言

实现高内聚,低耦合、结构清晰不臃肿、可读性高、数据冗余性低、高复用、易扩展的代码,并非易事。上到设计模式,下到某个类、方法、函数的构造。在这里我分享一下我自己的代码设计、编写风格,让我们互相学习。

Python代码风格

首先我们要以 PEP8 代码规范为标准,但也无需完全遵守。例如:一行不能超过 79 个字符等。

Python模块模板

  • 模块开头指定编码格式
  • 模块文档注释,展示模块的信息,信息内容自己决定,如:

    • Author,作者
    • Desc,模块描述
    • Date,创建时间
  • 有一个 main() 函数
  • 有一个程序主入口 if __name__ == '__main__':
#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Author: Hui
# @Desc: { 项目主入口模块 }
# @Date: 2020/05/21 13:04
def main():
    print('Hello Python')
if __name__ == '__main__':
    main()

main() 函数方便用于测试当前模块功能。

import 导入

import 导入,避免使用 from ... import * ,因为这可能导致模块、类、变量名重复而导致错误。
我自己的 import 代码风格有两种。

由短到长

根据代码的长度由短到长依次导入,import 过度到 from ... import ... ,换行分割可有可无,我是根据 from ... import ... 前面的 import 的数量和整体美观来决定要不要换行。

import os
import sys
import time
import random
import config
import pygame
import requests
import numpy as np
from PIL import Image
from threading import Thread
from datetime import datetime

分类导入

分类导入,是分好类后在根据代码的长度由短到长依次导入,主要有:

  • Python内置模块
  • Python自建模块
  • Python第三方库
# Python内置模块导入
import os
import sys
import time
import random
from threading import Thread
from datetime import datetime
# Python自建模块、第三方库导入
import config
import pygame
import requests
import numpy as np
from PIL import Image

导入顺序依次为

Python内置模块  -->  Python自建模块  -->  Python第三方库

根据自己的风格,导入的自建模块、Python第三方库少时可以在一起无需换行
导入的自建模块少时可以跟Python内置模块在一起,就是转换成 由短到长 的风格

建议

导入模块代码风格无需照搬照抄地遵循,我们做任何的优化就是为了让代码更好看,结构清晰,无需刻意遵循死规则、烂规则,应该活学活用,创新变化,学习别人优秀的方案,总结出适合自己的。
例如:
假如import 导入语句比 from 导入语句更长,要遵循或者纠结 import 是要在 from 导入语句前面还是由短到长排放呢?

import numpy as np
import multiprocessing
from PIL import Image
import numpy as np
from PIL import Image
import multiprocessing

无需太过纠结、抠字眼,两种导入风格都可以。

变量的命名规范

命名规范 可以被视为一种 惯例,并无绝对与强制 目的是为了 增加代码的识别和可读性

下划线命名法

  1. 在定义变量时,为了保证代码格式,= 的左右应该各保留一个空格
  2. Python 中,如果 变量名 需要由 二个多个单词 组成时,可以按照以下方式命名

    • 每个单词都使用小写字母
    • 单词与单词之间使用 _下划线 连接
    • 例如:first_namelast_nameqq_numberqq_password

驼峰命名法

  • 变量名 是由二个或多个单词组成时,还可以利用驼峰命名法来命名
  • 小驼峰式命名法

    • 第一个单词以小写字母开始,后续单词的首字母大写
    • 例如:firstNamelastName
  • 大驼峰式命名法

    • 每一个单词的首字母都采用大写字母
    • 例如:FirstNameLastNameCamelCase

驼峰命名法

Java、C 等其他语言一般用 驼峰命名法,在 Python 中则推荐使用 下划线命名法,符合 PEP8 规范。

Django 代码范例

模块导入

import re
import json
import logging
from django import http
from django.views import View
from django.conf import settings
from django.db import DatabaseError
from django.contrib.auth import authenticate
from django.contrib.auth import login, logout
from django_redis import get_redis_connection
from django.shortcuts import render, reverse, redirect
from goods.models import SKU
from users import constants
from users.models import User
from users.models import Address
from users.utils import generate_verify_email_url
from users.utils import check_verify_email_token
from carts.utils import merge_cart_cookie_to_redis
from meiduo_mall.utils.result import R
from meiduo_mall.utils.constants import RedisKey
from meiduo_mall.utils.constants import CookieKey
from meiduo_mall.utils.enums import StatusCodeEnum
from meiduo_mall.utils.constants import HtmlTemplate
from meiduo_mall.utils.views import LoginRequiredMixin
from meiduo_mall.utils.views import LoginRequiredJSONMixin
from meiduo_mall.utils.exceptions import BusinessException
from celery_tasks.email.tasks import celery_send_verify_email

这样导入看起来更舒服,有换行代码不紧凑,分类有条理。

封装html的url网址

渲染 html 页面,把 html 的存放路径总体封装到一个类里面,方便日后维护。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author: Hui
# @Desc: { 项目公共常量模块 }
# @Date: 2021/09/25 15:57
class HtmlTemplate(object):
    """
    项目 html网页模板路径汇总类
    """
    # 首页
    INDEX_HTML = 'index.html'
    """
    用户登录模块
    """
    # 用户登录
    LOGIN_HTML = 'users/login.html'
    # 用户注册
    REGISTER_HTML = 'users/register.html'
    # 用户中心个人信息
    USER_CENTER_INFO_HTML = 'users/user_center_info.html'
   
    """
    商品模块
    """
    # 商品列表
    GOODS_LIST_HTML = 'goods/list.html'
    # 商品详情
    GOODS_DETAIL_HTML = 'goods/detail.html'
   
    """
    购物车模块
    """
    # 购物车列表
    CART_LIST_HTML = 'carts/cart.html'
   
    """
    项目错误 html 模板
    """
    ERRORS_404_HTML = 'errors/404.html'

视图访问与渲染

from meiduo_mall.utils.constants import HtmlTemplate
# /
class IndexView(View):
    """首页类视图"""
    def get(self, request):
        context = {
            'name': 'hui'
        }
        return render(request, HtmlTemplate.INDEX_HTML, context)
   
# /login    
class LoginView(View):
    """用户登录类视图"""
    def get(self, request):
        """
        提供登录界面
        :param request: 请求对象
        :return: 登录界面
        """
        return render(request, HtmlTemplate.LOGIN_HTML)
   
   
# /register
class RegisterView(View):
    """用户注册类视图"""
    def get(self, request):
        """提供注册页面"""
        return render(request, HtmlTemplate.REGISTER_HTML)
   

设计与封装 Cookie 和 Redis 的键(key)

class CookieKey(object):
    """
    Cookie key 常量设计类
    """
    # 登录用户名 cookie key
    USERNAME_KEY = 'username'
    # 购物车信息 cookie key
    CARTS_KEY = 'carts'
class RedisKey(object):
    """
    redis key 常量设计类
    """
    # 图形验证码 key
    IMG_CODE_KEY = 'meiduo:img:code:{uuid}'
    # 短信验证码 key
    SMS_CODE_KEY = 'meiduo:sms:code:{mobile}'
    # 短信发送标记
    SMS_SEND_FLAG_KEY = 'meiduo:sms:send:flag:{mobile}'
    # 省份数据 key
    PROVINCES_KEY = 'meiduo:area:provinces'
    # 市区数据 key
    SUB_AREA_KEY = 'meiduo:sub_area:{area_id}'
    # 用户商品浏览记录
    HISTORY_BROWSE_KEY = 'meiduo:history:{user_id}'
    # 用户购物车数据 key
    USER_CARTS_KEY = 'meiduo:carts:{user_id}'
    # 购物车商品是否勾选 key
    CARTS_SELECTED_KEY = 'meiduo:cart:selected:{user_id}'

Rediskey 的名称,就非常见名知意。

项目名称 业务模块/功能 唯一标识
'meiduo:img:code:{uuid}'
'meiduo:sms:code:{mobile}'
'meiduo:carts:{user_id}'
'meiduo:history:{user_id}'

这里还有一个 settings 配置的常量设置

# redis 缓存 ip/port 信息
REDIS_URI = f"redis://{SERVER_IP}:6379"
# 缓存别名
DEFAULT_CACHE_ALIAS = 'default'
SESSION_CACHE_ALIAS = "session"
VERIFY_CODE_CACHE_ALIAS = 'verify_code'
HISTORY_CACHE_ALIAS = 'history'
CARTS_CACHE_ALIAS = 'carts'
# 缓存
CACHES = {
    # 默认采用0号Redis库。
    DEFAULT_CACHE_ALIAS: {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": f"{REDIS_URI}/0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    # session, 采用1号Redis库
    SESSION_CACHE_ALIAS: {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": f"{REDIS_URI}/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
   
   # 校验码(图片、短信验证码), 采用2号Redis库
    VERIFY_CODE_CACHE_ALIAS: {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": f"{REDIS_URI}/2",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    ...
}

封装前后代码对比

封装前

from django.conf import settings
from django_redis import get_redis_connection
from meiduo_mall.utils.constants import RedisKey
# 创建连接到redis的对象
redis_conn = get_redis_connection('verify_code')
img_code_key = 'meiduo:img:code:' + uuid  
image_code_server = redis_conn.get(img_code_key)

封装后

from django.conf import settings
from django_redis import get_redis_connection
from meiduo_mall.utils.constants import RedisKey
# 创建连接到redis的对象
redis_conn = get_redis_connection(settings.VERIFY_CODE_CACHE_ALIAS)
img_code_key = RedisKey.IMG_CODE_KEY.format(uuid=uuid)
image_code_server = redis_conn.get(img_code_key)

虽然封装的代码量添加了一些,但有助于你更快的了解项目大概做了什么,以及提高可维护性。不用到具体的模块、类、函数中一个个查看,日后更新只需在封装的类中改下即可。
注意:文章中有很多伪代码,主要是体现代码设计与编写的思想。

尾语

✍ 用 Code 谱写世界,让生活更有趣。❤️
✍ 万水千山总是情,点赞再走行不行。❤️
✍ 码字不易,还望各位大侠多多支持。❤️

相关文章
|
6天前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
65 1
|
9天前
|
机器学习/深度学习 算法 调度
基于多动作深度强化学习的柔性车间调度研究(Python代码实现)
基于多动作深度强化学习的柔性车间调度研究(Python代码实现)
|
7天前
|
IDE 开发工具 开发者
Python类型注解:提升代码可读性与健壮性
Python类型注解:提升代码可读性与健壮性
166 102
|
21天前
|
存储 缓存 测试技术
理解Python装饰器:简化代码的强大工具
理解Python装饰器:简化代码的强大工具
|
5天前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
72 2
|
9天前
|
安全 大数据 程序员
Python operator模块的methodcaller:一行代码搞定对象方法调用的黑科技
`operator.methodcaller`是Python中处理对象方法调用的高效工具,替代冗长Lambda,提升代码可读性与性能。适用于数据过滤、排序、转换等场景,支持参数传递与链式调用,是函数式编程的隐藏利器。
47 4
|
10天前
|
机器学习/深度学习 数据采集 并行计算
多步预测系列 | LSTM、CNN、Transformer、TCN、串行、并行模型集合研究(Python代码实现)
多步预测系列 | LSTM、CNN、Transformer、TCN、串行、并行模型集合研究(Python代码实现)
101 2
|
10天前
|
机器学习/深度学习 数据采集 算法
独家原创 | CEEMDAN-CNN-GRU-GlobalAttention + XGBoost组合预测研究(Python代码实现)
独家原创 | CEEMDAN-CNN-GRU-GlobalAttention + XGBoost组合预测研究(Python代码实现)
|
11天前
|
机器学习/深度学习 编解码 数据可视化
【能量算子】评估 EEG 中的瞬时能量:非负、频率加权能量算子(Python&Matlab代码实现)
【能量算子】评估 EEG 中的瞬时能量:非负、频率加权能量算子(Python&Matlab代码实现)
|
11天前
|
机器学习/深度学习 算法 安全
【强化学习应用(八)】基于Q-learning的无人机物流路径规划研究(Python代码实现)
【强化学习应用(八)】基于Q-learning的无人机物流路径规划研究(Python代码实现)