• (转)Python开发规范


    转自:https://www.jianshu.com/p/d414e90dc953

    Python风格规范 本项目包含了部分Google风格规范和PEP8规范,仅用作内部培训学习

    Python风格规范 本项目包含了部分Google风格规范和PEP8规范,仅用作内部培训学习


    命名规范

    Python之父推荐的规范

    TypePublicInternal
    Modules lower_with_under _lower_with_under
    Packages lower_with_under  
    Classes CapWords _CapWords
    Exceptions CapWords  
    Functions lower_with_under() _lower_with_under()
    Global/Class Constants CAPS_WITH_UNDER _CAPS_WITH_UNDER
    Global/Class Variables lower_with_under lower_with_under
    Instance Variables lower_with_under _lower_with_under (protected) or __lower_with_under (private)
    Method Names lower_with_under() _lower_with_under() (protected) or __lower_with_under() (private)
    Function/Method Parameters lower_with_under  
    Local Variables lower_with_under  

    应该避免的名称

    1.单字符名称
    2.包/模块名中使用连字符(-)而不使用下划线(_)
    3.双下划线开头并结尾的名称(如__init__)
    

    命名约定

    1.所谓”内部(Internal)”表示仅模块内可用, 或者, 在类内是保护或私有的.
    2.用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含).
    3.用双下划线(__)开头的实例变量或方法表示类内私有.
    4.将相关的类和顶级函数放在同一个模块里. 不像Java, 没必要限制一个类一个模块.
    5.对类名使用大写字母开头的单词(如CapWords, 即Pascal风格), 但是模块名应该用小写加下划线的方式(如lower_with_under.py).
    

    注释规范

    文档字符串

    Python使用文档字符串作为注释方式: 文档字符串是包, 模块, 类或函数里的第一个语句. 这些字符串可以通过对象的doc成员被自动提取, 并且被pydoc所用. 我们对文档字符串的惯例是使用三重双引号”“”( PEP-257 ).

    一个文档字符串应该这样组织:
    1. 首先是一行以句号, 问号或惊叹号结尾的概述(或者该文档字符串单纯只有一行). 接着是一个空行.
    2. 接着是文档字符串剩下的部分, 它应该与文档字符串的第一行的第一个引号对齐.

    """A user-created :class:`Response <Response>` object.
        
    Used to xxx a :class: `JsonResponse <JsonResponse>`, which is xxx
    
    :param data: response data
    :param file: response files
        
    Usage::
    
        >>> import api
        >>> rep = api.Response(url="http://www.baidu.com")
    """
    

    行内注释(PEP8)

    行内注释是与代码语句同行的注释
    1. 行内注释和代码至少要有两个空格分隔
    2. 注释由#和一个空格开始

    x = x + 1                 # Compensate for border
    

    模块

    每个文件应该包含一个许可样板. 根据项目使用的许可(例如, Apache 2.0, BSD, LGPL, GPL), 选择合适的样板.

    # -*- coding: utf-8 -*-
    # (C) JiaaoCap, Inc. 2017-2018
    # All rights reserved
    # Licensed under Simplified BSD License (see LICENSE)
    

    函数和方法

    一个函数必须要有文档字符串, 除非它满足以下条件:
    1. 外部不可见
    2. 非常短小
    3. 简单明了

    文档字符串应该包含函数做什么, 以及输入和输出的详细描述
    文档字符串应该提供足够的信息, 当别人编写代码调用该函数时, 他不需要看一行代码, 只要看文档字符串就可以了
    对于复杂的代码, 在代码旁边加注释会比使用文档字符串更有意义.

    def simple_func(method, timeout)
        """Constructs and sends a :class:`Request <Request>`.
        
        :param method: method for the new :class:`Request` object.
        :param timeout: (optional) How many seconds to wait for the server to send data
            before giving up, as a float, or a :ref:`(connect timeout, read
            timeout) <timeouts>` tuple.
        :type timeout: float or tuple
        :return: :class:`Response <Response>` object
        :rtype: requests.Response
        
        Usage::
        
          >>> import requests
          >>> req = requests.request('GET', 'http://httpbin.org/get')
          <Response [200]>
        """
    

    类应该在其定义下有一个用于描述该类的文档字符串. 如果你的类有公共属性(Attributes), 那么文档中应该有一个属性(Attributes)段. 并且应该遵守和函数参数相同的格式.

    class HTTPAdapter(BaseAdapter):
        """The built-in HTTP Adapter for urllib3.
    
        Provides a general-case interface for Requests sessions to contact HTTP and
        HTTPS urls by implementing the Transport Adapter interface.
    
        :param pool_connections: The number of urllib3 connection pools to cache.
        :param max_retries: The maximum number of retries each connection
            should attempt.
    
        Usage::
    
          >>> import requests
          >>> s = requests.Session()
          >>> a = requests.adapters.HTTPAdapter(max_retries=3)
          >>> s.mount('http://', a)
        """
       
        def __init__(self, pool_connections, max_retries):
            self.pool_connections = pool_connections
            self.max_retries = max_retries
    

    块注释和行注释

    对于复杂的操作, 应该在其操作开始前写上若干行注释. 对于不是一目了然的代码, 应在其行尾添加注释.

    # We use a weighted dictionary search to find out where i is in
    # the array.  We extrapolate position based on the largest num
    # in the array and the array size and then do binary search to
    # get the exact number.
    
    if i & (i-1) == 0:        # true iff i is a power of 2
    

    行长度

    1. 每行不超过80个字符
    2. 不要使用反斜杠连接行
    3. Python会将 圆括号, 中括号和花括号中的行隐式的连接起来 , 你可以利用这个特点. 如果需要, 你可以在表达式外围增加一对额外的圆括号.
    NO:
    query_sql = "SELECT image_id, image_o, image_width, image_height "
                "FROM active_image_tbl "
                "WHERE auction_id=:auction_id AND status=1 " 
                "ORDER BY image_id DESC"
       
    YES:         
    agent_sql = ("CREATE TABLE IF NOT EXISTS db_agent ("
                 "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                 "device_id VARCHAR(128) DEFAULT '', "
                 "status INTEGER DEFAULT 1, "
                 "updated_time TIMESTAMP  DEFAULT CURRENT_TIMESTAMP, "
                 "created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")
    
    
    在注释中,如果必要,将长的URL放在一行上。
    Yes: 
    # See details at
    # http://www.example.com/us/developer/documentation/api/content/v2.0/fication.html
    

    换行

    1. 使用4个空格来缩进代码
    2. 对于行连接的情况, 你应该要么垂直对齐换行的元素, 或者使用4空格的悬挂式缩进(这时第一行不应该有参数):
    # 垂直对齐换行的元素
    foo = long_function_name(var_one, var_two,
                             var_three, var_four)
    
    
    # 4空格的悬挂式缩进(这时第一行不应该有参数)
    foo = long_function_name(
        var_one, var_two, var_three,
        var_four)
    

    空格

    1. 括号内不要有空格
    YES:
    spam(ham[1], {eggs: 2}, [])                 # 注意标点两边的空格
    
    NO:
    spam( ham[ 1 ], { eggs: 2 }, [ ] )
    
    1. 不要在逗号,分号,冒号前面加空格,而应该在它们的后面加
    YES:
    if x == 4:
        print x, y
    x, y = y, x 
    
    NO:
    if x == 4 :
       print x , y
    x , y = y , x
    
    1. 二元操作符两边都要加上一个空格(=, ==,<, >, !=, in, not ...)
    2. 当’=’用于指示关键字参数或默认参数值时
    def complex(real, imag=0.0): 
        return magic(r=real, i=imag)
    
    1. 不要用空格来垂直对齐多行间的标记, 因为这会成为维护的负担(适用于:, #, =等)
    YES:
    foo = 1000  # comment
    long_name = 2  # comment that should not be aligned
    
    NO:
    foo       = 1000  # comment
    long_name = 2     # comment that should not be aligned
    

    模块导入

    1. 每个导入应该独占一行
    YES:
    import os
    import sys
    from subprocess import Popen, PIPE      # PEP8
    
    NO:
    import sys, os
    
    1. 模块导入顺序
      1. 标注库导入
      2. 第三方库导入
      3. 应用程序指定导入
    2. 每种分组中, 应该根据每个模块的完整包路径按字典序排序, 忽略大小写.
    import foo
    from foo import bar
    from foo.bar import baz
    from foo.bar import Quux
    from Foob import ar
    

    TODO注释

    1. TODO注释应该在所有开头处包含”TODO”字符串, 紧跟着是用括号括起来的你的名字, email地址或其它标识符. 然后是一个可选的冒号. 接着必须有一行注释, 解释要做什么
    2. 如果你的TODO是”将来做某事”的形式, 那么请确保你包含了一个指定的日期(“2009年11月解决”)或者一个特定的事件
    # TODO(kl@gmail.com): Use a "*" here for string repetition.
    # TODO(Zeke) Change this to use relations.
    

    二元运算符换行(PEP8)

    # 不推荐: 操作符离操作数太远
    income = (gross_wages +
              taxable_interest +
              (dividends - qualified_dividends) -
              ira_deduction -
              student_loan_interest)
     
    
    # 推荐:运算符和操作数很容易进行匹配
    income = (gross_wages
              + taxable_interest
              + (dividends - qualified_dividends)
              - ira_deduction
              - student_loan_interest)
    

    其它规范

    1. 不要在行尾加分号, 也不要用分号将两条命令放在同一行.
    2. 除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.
    3. 顶级定义之间空两行, 方法定义之间空一行

    Pandas使用规范

    1. pandas数据结构命名 df_、se_
    2. df取一列,禁止使用df.列名,可以使用df['列名'], 建议使用df.loc[:, '列名']
    3. 禁止使用df.ix

    目录结构示例

    |--docs
    |--requests
    |    |--__init__.py
    |    |--_internal_utils.py
    |    |--utils.py
    |    |--api.py
    |--tests
    |--setup.py
    |--README.rst
    |--LICENSE  
    

    Class结构示例

    # -*- coding: utf-8 -*-
    # (C) JiaaoCap, Inc. 2017-2018
    # All rights reserved
    # Licensed under Simplified BSD License (see LICENSE)
    
    """
    requests.api
    
    This module contains xxx. 
    This module is designed to xxx.
    """
    
    # stdlib
    import os
    import time
    
    from base64 import b64encode
    
    # 3p
    try:
        import psutil
    exception ImportError:
        psutil = None
    import simplejson as json
    
    # project
    from .utils import current_time
    from ._internal_utils import internal_func
    
    
    class Response(object):
        """A user-created :class:`Response <Response>` object.
        
        Used to xxx a :class: `JsonResponse <JsonResponse>`, which is xxx
        
        :param data: response data
        :param file: response files
            
        Usage::
        
            >>> import api
            >>> rep = api.Response(url="http://www.baidu.com")
        """
        
        def __init__(self, data, files, json, url)
            self.data = data
        
        @staticmethod
        def _sort_params(params):
            """This is a private static method"""
            return params   
    
        def to_json():
            """The fully method blala bian shen,
            xxx sent to the server.
                
            Usage::
            
                >>> import api
                >>> rep = api.Response(url="http://www.baidu.com")
                >>> rep.to_json()
            """
            
            if self.url == "www":
                return True
            return False
    

    相关链接

  • 相关阅读:
    JAVA知识点在整理(可供面试参考)
    Spring Destroying singletons ... root of factory hierarchy 问题【已解决】
    《Spring AOP的设计和实现方式》
    java源码集合体系解析
    springcloud的一些自己想法
    部署一套单Master的K8s集群
    K8S系统学习-----Pod 容器组
    RH358学习笔记--8(使用HAProxy终止HTTPS流量和并进行负载均衡)
    Docker 资源汇总
    RH358学习笔记--8(使用Nginx配置Web服务器学习)
  • 原文地址:https://www.cnblogs.com/daxiong2014/p/10421681.html
Copyright © 2020-2023  润新知