论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
相关文章
|
2月前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
56 6
|
3月前
|
存储 缓存 测试技术
Python中的装饰器:功能增强与代码复用的利器
在Python编程中,装饰器是一种强大而灵活的工具,它允许开发者以简洁优雅的方式增强函数或方法的功能。本文将深入探讨装饰器的定义、工作原理、应用场景以及如何自定义装饰器。通过实例演示,我们将展示装饰器如何在不修改原有代码的基础上添加新的行为,从而提高代码的可读性、可维护性和复用性。此外,我们还将讨论装饰器在实际应用中的一些最佳实践和潜在陷阱。
|
23天前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
58 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
2月前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
78 33
|
3月前
|
人工智能 数据挖掘 Python
Python编程基础:从零开始的代码旅程
【10月更文挑战第41天】在这篇文章中,我们将一起探索Python编程的世界。无论你是编程新手还是希望复习基础知识,本文都将是你的理想之选。我们将从最基础的语法讲起,逐步深入到更复杂的主题。文章将通过实例和练习,让你在实践中学习和理解Python编程。让我们一起开启这段代码之旅吧!
|
2月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
52 10
|
2月前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
105 8
|
2月前
|
API Python
【Azure Developer】分享一段Python代码调用Graph API创建用户的示例
分享一段Python代码调用Graph API创建用户的示例
68 11
|
2月前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
57 11
|
2月前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!

热门文章

最新文章

推荐镜像

更多