python编程规范

说明

代码的交互作用不能仅限于人与机器,更应该扩展到人与人,所以才有代码规范这一需求;一段好的代码不仅需要结构简单、功能块分工明确,而且别人能容易读懂。
使用Pycharm等 IDE可以设置自己喜欢的代码风格,这种规范好的代码风格可以帮助新手规避掉很多常识性错误,本文档在此不做叙述(如果有兴趣可以通读python规范.pdf)。接下就“Imports 导⼊”、“注释”、“命名”、“代码结构”4个主题构建规范。

Imports 导⼊规范

格式要求

当没有 from 语句的导入必须分⾏写(习惯按导入模块的首字母排序),形如:

import os 
import sys

如果有 from 语句,可以使⽤用如下⽅式,形如:

from subprocess import Popen, PIPE

如果有本地模块,建议使用绝对路径(在服务器中使用相对路径可能会出现意外的错误:如crontab无法识别相对路径的模块),也可以选择将模块添加到sys.path,形如:

sys.path.insert(0, '/DATA/hdfs/lwb/pyspark/ticket/ticket_feature')
from com.spark_dataframe import SimplifyProcess, SparkUdf

注意: 导入模块时不要贪图省事使用通配符 *

位置

导⼊总是位于文件的顶部,在模块注释和⽂文档字符串之后,在模块的全局变量与常量之前,形如:

# -*- coding: utf-8 -*-
"""
模块注释
"""
import sys # 导入
GLOBAL_VARIABLE = 1 # 全局变量(常量)
顺序

导入模块需要按以下顺序分组:

  1. 标准库导入
  2. 第三方库导入
  3. 本地模块导入

注意:一个导入分组间需要加入空行,形如:

import datetime
import sys

from pyspark.sql import SparkSession
from pyspark.sql.functions import max
from pyspark.sql.types import StringType

sys.path.insert(0, '/DATA/hdfs/lwb/pyspark/ticket/ticket_feature')
from com.spark_dataframe import SimplifyProcess, SparkUdf

注释规范

代码块注释

代码块注释通常适用于跟随它们的某些(或全部)代码,并缩进到与代码相同的级别。注释的⾏开头使⽤一个#和⼀个空格。形如:

# 国内机场
airport_list = sc.textFile("hdfs://umecluster/apps/hive/warehouse/"
						 "dim_db.db/dim_airport_detail") \
    .map(lambda x: x.split("\x01")) \
    .filter(lambda x: x[9] == "1" and x[16] == "1") \
    .map(lambda x: x[0]) \
    .collect()
行内注释

⾏内注释是与代码语句同⾏的注释。⾏内注释和代码至少要有两个空格分隔。注释由 # 和⼀个空格开始。形如:

if serializer.is_valid(): # 验证表单 => ⾏内注释
    user = serializer.validated_data['user']
文档注释

公共模块,函数,类以及方法需要编写文档说明。非公共的方法没有必要,但是应该 有一个描述方法具体作⽤的注释。形如:
公共模块注释:

"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""

公共方法注释:

def data_list(column, size):
    """
    size是滑动窗的大小
    :param column: 当前generated_date
    :return: 窗内generated_date list
    """

对于单⾏的⽂档说明,尾部的三引号应该和文档在同一⾏,形如:

 class UserInfo(models.Model): 
     """⽤用户信息表"""

命名规范

命名要尽量有意义,必须使⽤英文单词,不允许使用汉语拼⾳更不能使用汉语拼音和英文单词混
用。

包、模块、类命名

考虑模块名是与文件夹相对应,因此需要考虑文件系统的一些命名规则的,比如Unix系统对大小写敏感,而过长的文件名会影响其在 Windows\Mac\Dos 等系统中的正常使用。

模块应该使用尽可能短的、全小写命名,可以在模块命名时使用下划线以增强可读性。同样包的命名也应该是这样的,虽然其并不鼓励下划线。形如:
ad_stats.py

类名都使用首字母大写开头(Pascal命名风格)的规范,推荐使用驼峰命名法,例如:CapitalizedWords。使用 _单下划线开头的类名为内部使用;使用通配符 *调用类时会自动过滤掉这种仅内部使用类,形如:

from module_name import *
output: ignore class _InnerClass
常量和变量命名
常量

常量通常定义在模块级,通过下划线分隔的全大写字母命名,形如: MAX_OVERFLOW 和TOTAL

全局变量

命名规则为单词全大写,单词之间用 _分割,形如:

NUMBER
COLOR_WRITE
普通变量

命名规则为单词全小写,单词之间用 _分割,形如:

this_var

注意:变量名不应带有类型信息,因为Python是动态类型语言。不推荐的命名形如:
names_list、dict_obj

特殊变量
  • 实例变量

实例变量的命名建议以 _开头,其他命名规则与普通变量一样,形如:

class DataTransform(object):
    def __init__(self, _days):
        self._days = _days # 类的实例变量
        pass

使用这种方式命名的实例变量是对外公开的,类本身和子类能访问到该实例变量(等效protected)。

  • 私有实例变量

私有实例变量的命名建议以 __开头,其他命名规则与普通变量一样,形如:

class DataTransform(object):
    def __init__(self, __df):
        self.__df = __df # 类的私有实例变量
        pass

使用这种方式命名的实例变量仅有类本身能访问,外部访问会报错(等效private)。

  • 专有变量

专有变量的命名以__开头,__结尾,这种变量一般为python自有变量,形如:

__doc__
__class__

建议:不要以这种方式命名普通变量,这个是保留字,要满足防御性编程需求。

函数命名
普通函数

普通函数命名和普通变量一样

get_name()
count_number()

还有一类函数以_开头,形如_get_name,这种函数只允许其本身与子类进行访问(等效protected),不能用于 from module import *,其他与普通函数无异。

私有函数

私有函数命名以__开头,其他和普通函数一样

__get_name()
使用这种方式命名的函数仅限于本类使用,子类调用会报错(等效private)。
特殊函数

主要是指 __xxx__形式的系统保留字命名法。一般是系统定义名字 ,类似 __init__()。除了作为文档之外,永远不要命这样的名。

代码结构规范

该部分总结了一部分好的编程习惯和一些约定俗成的规定。

异常处理和日志
  • 在编写代码时需要培养使用日志的习惯(使用logging而不是print打日志),日志的重要性和灵活性在此不做赘述。
  • 不要把所有代码放到try except中, 只捕获会出异常的代码片段. 注意粒度, 不要放入不必要的代码。
  • 谨慎使用except Exception捕获所有异常;不要吞掉异常, 处理或抛出, 同时要打异常日志。
函数设计
  • 编写函数时控制住函数大小(习惯上函数的大小不超过100行),尽量保证一个函数做一件事
  • 抽取反复出现重复的代码到独立函数中;形如下例spark中对列做独热编码:
    独热编码是将一列中所有出现的值,构建成新的列;做完编码后将原有列清除,下面的例子是对某一列做独热编码。
col = "adept"
value = ['PVG', 'CAN', 'CTU', 'SZX', 'PEK', 'KMG', 'SHA', 'XIY', 'CKG', 'HGH']
_df = _df.withColumn("adept_PVG"), 
					 when(_df["adept"] == "PVG", lit(1)).otherwise(lit(0))) \
		 .withColumn("adept_CAN"), 
		 			 when(_df["adept"] == "CAN", lit(1)).otherwise(lit(0))) \ 
		 ...
		 ...
		 .withColumn("adept_HGH"), 
		 			 when(_df["adept"] == "HGH", lit(1)).otherwise(lit(0)))
_df = _df.select([c for c in _df.columns if c not in {"adept"}])

在编码过程中同一个操作重复多次,可以考虑将该操作抽取到独立函数中,下面的oneHot_encode函数就是对上述操作的抽取整合。

def oneHot_encode(_df, col, value=None):
    """
    指定的列做onehot编码
    :param _df:
    :param col: 指定列
    :param value: 指定列中值的集合
    :return: 去掉做编码操作的原有列
    """
    if value is None:
        rdd_tmp = _df.select(col).dropDuplicates().collect()
        addCol = [row[col] for row in rdd_tmp]
    else:
        addCol = value
    for column_ in addCol:
        # 新建onehot列
        _df = _df.withColumn(col + "_" + str(column_), when(_df[col] == column_, lit(1)).otherwise(lit(0)))
    _df = _df.select([c for c in _df.columns if c not in {col}])
    return _df
  • 多个函数间相似度较高可以考虑抽象提取封装
  • 切记,函数设计不能过分追求通用
其他
  • 空行用以将逻辑相关的代码段分隔开,以提高可读性。两个逻辑代码块之间应该保留一个空行,形如:
def dataSet():
    # 国内机场
    airport_list = sc.textFile("hdfs://umecluster/apps/hive/warehouse/"
    						   "dim_db.db/dim_airport_detail") \
        ...
        ...
        .collect()

    partion = YESTERDAY
    # 计划航班数据
    days = Stock.data_list(partion, 7)
    ...
    ...
    plan_df = plan_df.select(["flightnumber", "schdate", "adept", "adest", "ptdLabel"])

    # 库存数据
    date = Stock.data_list(partion, 8)
    host_ = "hdfs://umecluster/user/ume/ticket/data/flight_inv/legcabininfo/"
    ...
    ...
    stock_df = stock_df.filter(stock_df.legclazz == "Y")
    return stock_df, plan_df
  • 熟悉标准库, 减少土制轮子的概率, 可以少写代码,提高代码执行效率
  • 熟悉框架/优秀第三方库提供的接口及特性, 原因同上
Python编程规范是指在编写Python代码时应遵循的一系列规则和准则,以提高代码的可读性、可维护性和可扩展性。主要有两个主流的编程规范指南:PEP 8和Google开源项目风格指南。 PEP 8是Python Enhancement Proposal的缩写,是Python社区广泛接受的编程规范指南。它提供了关于代码布局、命名规范、注释、代码风格等方面的建议。以下是PEP 8的一些主要规范: - 使用4个空格作为缩进,而不是制表符。 - 每行代码不超过79个字符。 - 使用空行来分隔函数和类,以及函数内的逻辑块。 - 使用空格来分隔运算符和逗号,但不要在括号内部使用空格。 - 使用全小写字母和下划线来命名变量、函数和模块。 - 使用驼峰命名法来命名类。 - 在逻辑行的末尾使用反斜杠来换行。 - 使用文档字符串来描述模块、函数和类的功能。 Google开源项目风格指南是Google公司针对Python编程规范指南。它与PEP 8有一些不同之处,但也提供了一些有用的编程准则。以下是Google开源项目风格指南的一些主要规范: - 使用2个空格作为缩进,而不是制表符。 - 每行代码不超过80个字符。 - 使用空行来分隔函数和类,以及函数内的逻辑块。 - 使用空格来分隔运算符和逗号,但不要在括号内部使用空格。 - 使用全小写字母和下划线来命名变量、函数和模块。 - 使用驼峰命名法来命名类。 - 在逻辑行的末尾使用反斜杠来换行。 - 使用文档字符串来描述模块、函数和类的功能。 总之,遵循编程规范可以使代码更易读、易懂和易于维护。根据个人喜好和项目需求,可以选择PEP 8或Google开源项目风格指南作为编程规范的参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值