论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 谱写世界,让生活更有趣。❤️
✍ 万水千山总是情,点赞再走行不行。❤️
✍ 码字不易,还望各位大侠多多支持。❤️

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1天前
|
缓存 开发者 Python
探索Python中的装饰器:简化和增强你的代码
【10月更文挑战第32天】 在编程的世界中,简洁和效率是永恒的追求。Python提供了一种强大工具——装饰器,它允许我们以声明式的方式修改函数的行为。本文将深入探讨装饰器的概念、用法及其在实际应用中的优势。通过实际代码示例,我们不仅理解装饰器的工作方式,还能学会如何自定义装饰器来满足特定需求。无论你是初学者还是有经验的开发者,这篇文章都将为你揭示装饰器的神秘面纱,并展示如何利用它们简化和增强你的代码库。
|
2天前
|
机器学习/深度学习 自然语言处理 API
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程。通过简单的代码示例,展示如何将文本转换为自然流畅的语音,适用于有声阅读、智能客服等场景。
18 3
|
4天前
|
设计模式 缓存 测试技术
Python中的装饰器:功能增强与代码复用的艺术####
本文将深入探讨Python中装饰器的概念、用途及实现方式,通过实例演示其如何为函数或方法添加新功能而不影响原有代码结构,从而提升代码的可读性和可维护性。我们将从基础定义出发,逐步深入到高级应用,揭示装饰器在提高代码复用性方面的强大能力。 ####
|
2天前
|
算法 IDE API
Python编码规范与代码可读性提升策略####
本文探讨了Python编码规范的重要性,并深入分析了如何通过遵循PEP 8等标准来提高代码的可读性和可维护性。文章首先概述了Python编码规范的基本要求,包括命名约定、缩进风格、注释使用等,接着详细阐述了这些规范如何影响代码的理解和维护。此外,文章还提供了一些实用的技巧和建议,帮助开发者在日常开发中更好地应用这些规范,从而编写出更加清晰、简洁且易于理解的Python代码。 ####
|
5天前
|
缓存 测试技术 数据安全/隐私保护
探索Python中的装饰器:简化代码,增强功能
【10月更文挑战第29天】本文通过深入浅出的方式,探讨了Python装饰器的概念、使用场景和实现方法。文章不仅介绍了装饰器的基本知识,还通过实例展示了如何利用装饰器优化代码结构,提高代码的可读性和重用性。适合初学者和有一定经验的开发者阅读,旨在帮助读者更好地理解和应用装饰器,提升编程效率。
|
12天前
|
开发者 Python
探索Python中的装饰器:简化代码,增强功能
【10月更文挑战第22天】在Python的世界里,装饰器是一个强大的工具,它能够让我们以简洁的方式修改函数的行为,增加额外的功能而不需要重写原有代码。本文将带你了解装饰器的基本概念,并通过实例展示如何一步步构建自己的装饰器,从而让你的代码更加高效、易于维护。
|
9天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
12 3
|
13天前
|
开发框架 Python
探索Python中的装饰器:简化代码,增强功能
【10月更文挑战第20天】在编程的海洋中,简洁与强大是航行的双桨。Python的装饰器,这一高级特性,恰似海风助力,让代码更优雅、功能更强大。本文将带你领略装饰器的奥秘,从基础概念到实际应用,一步步深入其内涵与意义。
|
12天前
|
机器学习/深度学习 缓存 数据挖掘
Python性能优化:提升你的代码效率
【10月更文挑战第22天】 Python性能优化:提升你的代码效率
10 1
|
14天前
|
机器人 Shell Linux
【Azure Bot Service】部署Python ChatBot代码到App Service中
本文介绍了使用Python编写的ChatBot在部署到Azure App Service时遇到的问题及解决方案。主要问题是应用启动失败,错误信息为“Failed to find attribute 'app' in 'app'”。解决步骤包括:1) 修改`app.py`文件,添加`init_func`函数;2) 配置`config.py`,添加与Azure Bot Service认证相关的配置项;3) 设置App Service的启动命令为`python3 -m aiohttp.web -H 0.0.0.0 -P 8000 app:init_func`。