Maison  >  Article  >  développement back-end  >  Introduction détaillée au format de codage Python (avec exemples)

Introduction détaillée au format de codage Python (avec exemples)

不言
不言avant
2019-01-28 10:56:453569parcourir

Cet article vous apporte une introduction détaillée au format de codage Python (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

En plus de l'exécution, le code est également utilisé pour la lecture. Afin de rendre le code plus lisible, de nombreux langages de programmation disposent de leurs propres normes de codage. Les spécifications sont développées pour maintenir la cohérence du code afin de le rendre plus beau et plus lisible. La manière dont le code doit être formaté et écrit n’est pas absolue, certains domaines seront donc controversés. Parfois, les guides de style ne s’appliquent pas, et le plus important est de savoir quand être incohérent. Lorsque vous ne savez pas quoi faire, vous devriez vous tourner vers d’autres exemples.

Cet article n'est qu'une référence pour le style de codage Python, pas une règle qui stipule que cela doit être fait. Le but de cet article devrait être de servir de guide pour guider les développeurs dans l’écriture d’un code plus lisible.

1. Disposition du code

Principalement la disposition de l'indentation et des lignes vides :

  • Utilisez 4 espaces pour indenter. (n'importe quel éditeur peut remplir cette fonction), les tabulations ne sont pas recommandées et les tabulations et les espaces ne peuvent pas être mélangés.

  • 2. Chaque ligne ne doit pas dépasser 80 caractères. Vous pouvez utiliser des barres obliques inverses pour les sauts de ligne. Il est préférable d'utiliser des crochets (Python sera implicitement connecté).

  • 3. Deux lignes vides entre les définitions de classe et de fonction de niveau supérieur ; une ligne vide entre les définitions de méthodes dans les classes ; une ligne vide entre les paragraphes logiquement non pertinents dans les fonctions ; dans d'autres endroits Ligne vide.

Principalement la disposition de l'ensemble du fichier de code source :

  • 1. L'ordre du contenu du module : description du module, documentation du module. chaîne, instructions d'importation, variables ou constantes globales et autres définitions.

  • 2. L'ordre des parties d'importation du module : bibliothèque standard, module tiers, module personnalisé il y a une ligne vierge entre chaque partie.

  • 3. N'importez pas plusieurs modules à la fois dans une seule instruction d'importation, comme import os, sys n'est pas recommandé.

  • 4. Lors de l'importation de modules, vous devez utiliser les méthodes appropriées pour éviter les conflits de noms. Par exemple, utilisez from xx import xx uniquement lorsque cela est approprié et essayez d'éviter d'utiliser from xx imoprt *.

  • 5. Dans un module auto-écrit, si vous devez utiliser from xx import *, vous devez utiliser le mécanisme __all__ après l'instruction d'importation ou à la fin du module pour limiter les règles d’importation.

3. Disposition des relevés

  • 1. Habituellement, chaque relevé doit être sur sa propre ligne.

  • 2. N'ajoutez pas de point-virgule à la fin de la ligne et n'utilisez pas de points-virgules pour mettre plusieurs instructions sur la même ligne.

  • 3. Dans l'instruction if/for/while, même s'il n'y a qu'une seule instruction d'exécution, essayez de démarrer une nouvelle ligne.

  • 4. N'utilisez pas de parenthèses dans les instructions return (return) ou les instructions conditionnelles (if/for/while) à moins qu'elles ne soient utilisées pour implémenter des connexions de lignes.

  • 5. Pour les instructions if, lorsqu'il n'y a pas d'autre et que l'instruction est relativement courte, elle peut être complétée sur une seule ligne (mais ce n'est pas recommandé), comme : if foo: bar(foo).

  • 6. Pour une définition simple de classe, elle peut également être complétée sur une seule ligne (mais non recommandé), comme définir une exception : class UnfoundError(Exception): pass.

  • 7. Fonctions et méthodes Utilisez une indentation implicite verticale entre parenthèses ou utilisez une indentation suspendue.

# 一行写不下时,有括号来连接多行,后续行应该使用悬挂缩进
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

# 函数调用参数较多时,对准左括号
f = foo(a, b,
        c, d)

# 不对准左括号,但加多一层缩进,以和后面内容区别
def long_function_name(
        a, b, c,
        d, e):
    print(a, b, c, d, e)

# 列表、元组、字典以及函数调用时可以让右括号回退,这样更加美观
l = [
    1, 2, 3,
    4, 5, 6,
]

result = some_function(
    'a', 'b', 'c',
    'd', 'e', 'f',
)

4. Utilisez le principe général de

pour les espaces afin d'éviter les espaces inutiles.

  • 1. N'ajoutez pas d'espaces avant les diverses parenthèses fermantes.

  • 2. N'ajoutez pas d'espaces avant les virgules, les deux-points et les points-virgules, mais ils doivent être ajoutés après eux (sauf en fin de ligne).

  • 3. N'ajoutez pas d'espace avant le crochet gauche de la fonction. Tel que Func(1).

  • 4. N'ajoutez pas d'espace avant le crochet gauche de la séquence. Tel que la liste[2].

  • 5. Ajoutez un espace à gauche et à droite de l'opérateur. N'ajoutez pas d'espaces pour l'alignement.

  • 6. Omettez les espaces autour des caractères d'affectation utilisés par les paramètres par défaut de la fonction.

Bon style :

spam(ham[1], {eggs: 2})

if x == 4:
    print x, y; x, y = y, x

f = foo(1, 2, 3)

ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]

x = 1
y = 2
long_variable = 3

def foo(a, b, c=0):
    return moo(m=a, n=b, o=c)

Mauvais style :

spam( ham[ 1 ], { eggs: 2 } )

if x == 4 :
    print x , y ; x , y = y , x

f = foo (1, 2, 3)

ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]

x             = 1
y             = 2
long_variable = 3

def foo(a, b, c = 0):
    return moo(m = a, n = b, o = c)

Notes

Principes généraux, un faux un commentaire est pire que pas de commentaire du tout. Ainsi lorsqu’un morceau de code change, la première chose à faire est de modifier les commentaires. Les commentaires doivent être en anglais autant que possible. Il est préférable d'utiliser des phrases complètes, avec la première lettre en majuscule. Il doit y avoir un terminateur après la phrase. Le terminateur doit être suivi de deux espaces pour commencer la phrase suivante. S'il s'agit d'une phrase, le terminateur peut être omis. Les commentaires doivent commencer par un espace après #.

  • 1. Bloquer le commentaire, un commentaire ajouté avant un morceau de code. Utilisez des lignes avec seulement « # » entre les paragraphes. Par exemple :

# Description : Module config.
#
# Input : None
#
# Output : None
  • 2. Commentaires en ligne, ajoutez des commentaires après une ligne de code. Vous devriez essayer de laisser deux espaces après la déclaration avant de commencer le commentaire. Lorsqu'il y a des commentaires en ligne continue, « # » peut être aligné pour des raisons d'apparence. Lorsque les instructions sont longues, les commentaires de ligne doivent être utilisés le moins possible. Par exemple :

person = {
    "name": "huoty",  # 姓名
    "age": 26,        # 年龄
    "stature": 169,   # 身高
    "weight": 60,     # 体重
}

print person  # 输出信息
  • 3、对类或者函数的说明,尽量不要在其定义的前一行或者后一行用块注释的形式来说明,而应该使用文档字符串(docstring)

  • 4、使用 TODO 注释来标记待完成的工作,团队协作中,必要的时候应该写上你的名字或者联系方式,比如:

# TODO(sudohuoty@gmail.com): Use a "*" here for string repetition.
# TODO(Huoty) Change this to use relations.
  • 5、避免无谓的注释。你见过哪些奇趣的代码注释?

# 你可能会认为你读得懂以下的代码。但是你不会懂的,相信我吧。  

# 要是你尝试玩弄这段代码的话,你将会在无尽的通宵中不断地咒骂自己为什么会认为自己聪明到可以优化这段代码。  
# so,现在请关闭这个文件去玩点别的吧。  

# 程序员1(于2010年6月7日):在这个坑临时加入一些调料  
# 程序员2(于2011年5月22日):临你个屁啊  
# 程序员3(于2012年7月23日):楼上都是狗屎,鉴定完毕  
# 程序员4(于2013年8月2日):fuck 楼上,三年了,这坑还在!!!  
# 程序员5(于2014年8月21日):哈哈哈,这坑居然坑了这么多人,幸好我也不用填了,系统终止运行了,you're died

六、文档描述

  • 1、尽量为所有的共有模块、函数、类、方法写 docstring

  • 2、前三引号后不应该换行,应该紧接着在后面概括性的说明模块、函数、类、方法的作用,然后再空一行进行详细的说明。后三引号应该单独占一行。比如:

"""Convert an API path to a filesystem path

If given, root will be prepended to the path.
root must be a filesystem path already.
"""
  • 2、函数和方法的 docstring 层次顺序大致为概述、详细描述、参数、返回值、异常,一般不要求描述实现细节,除非其中涉及非常复杂的算法。大致的层次结构如下所示:

"""函数或方法的概述

详细的描述信息……
详细的描述信息……

参数说明
--------
    参数1:...
    参数2:...

返回值:
    ...

异常:
    异常1:...
    异常2:...
"""

一个参考示例:

"""Start a kernel for a session and return its kernel_id.                                                                                             

Parameters
----------
kernel_id : uuid
    The uuid to associate the new kernel with. If this
    is not None, this kernel will be persistent whenever it is
    requested.
path : API path
    The API path (unicode, '/' delimited) for the cwd.
    Will be transformed to an OS path relative to root_dir.
kernel_name : str
    The name identifying which kernel spec to launch. This is ignored if
    an existing kernel is returned, but it may be checked in the future.

Return a kernel id
"""
  • 3、类的 docstring 的层次顺序大致为概述、详细描述、属性说明。如果类有公开属性值时,应该尽量在 docstring 中进行说明。如下所示:

"""这里是类的概述。

详细的描述信息……
详细的描述信息……

属性(Attributes):
-----------------
    属性1: ...
    属性2: ...
"""

七、命名规范

  • 1、模块命名尽量短小,使用全部小写的方式,可以使用下划线。

  • 2、包命名尽量短小,使用全部小写的方式,不可以使用下划线。

  • 3、类的命名使用驼峰命令的方式,即单词首字符大写,类名应该全部使用名词。

  • 4、异常命令应该使用加 Error 后缀的方式,比如:HTTPError。

  • 5、全局变量尽量只在模块内有效,并且应该尽量避免使用全局变量。

  • 6、函数命名使用全部小写的方式,使用下划线分割单词,并采用动宾结构。

  • 7、常量命名使用全部大写的方式,使用下划线分割单词。

  • 8、类的属性(方法和变量)命名使用全部小写的方式,使用下划线分割单词。

  • 9、变量、类属性等命令尽量不要使用缩写形式,除了计数器和迭代器,尽量不要使用单字符名称。

  • 10、类的方法第一个参数必须是 self,而静态方法第一个参数必须是 cls。

  • 11、在模块中要表示私有变量或者函数时,可以在变量或者函数前加一个下划线 _foo, _show_msg 来进行访问控制。

  • 12、在 Python 中没有诸如 public、private、protected 等修饰符,而在类的定义中往往会有类似这样的需求,那么可以在属性或者方法前加一个下划线表示 protected,加两个下划线来表示 private。加两个下划线的变量或者方法没法直接访问。比如:类 Foo 中声明 __a, 则不能用 Foo.__a 的方式访问,但可以用 Foo._Foo__a 的方式访问。`

八、程序入口

Python 属于脚本语言,代码的运行是通过解释器对代码文件进行逐行解释执行来完成的。它不像其他编程语言那样有统一的入口程序,比如 Java 有 Main 方法,C/C++ 有 main 方法。Python 的代码文件除了可以被直接执行外,还可以作为模块被其他文件导入。所有的顶级代码在模块导入时都会被执行,当希望模块被导入时,应该避免主程序被执行。这样就需要把主程序放到 if __name__ == '__main__' 代码块中,比如:

def main():
      ...

if __name__ == '__main__':
    main()

一个包除了能够被导入外,也可以通过 python -m package 的方式被直接执行,前提是包中需要有 __main__.py,这个文件可以说是包的程序入口,包中有了这个文件就可以用 Python 的 -m 参数来直接运行。

九、编码建议

  • 1、尽可能使用 'is' 和 'is not' 取代 '==',比如 if x is not None 要优于 if x != None,另外用 if x 效率更高。

Note: 等于比较运算符(==) 会调用左操作数的 __eq__ 函数,这个函数可以被其任意定义,而 is 操作只是做 id 比较,并不会被自定义。同时也可以发现 is 函数是要快于等于运算符的,因为不用查找和运行函数。

  • 2、用 "is not" 代替 "not ... is",前者的可读性更好。

  • 3、使用基于类的异常,每个模块或包都有自己的异常类,此异常类继承自 Exception。

  • 4、异常中尽量不要使用裸露的 except,except 后应该跟具体的 exceptions。

  • 5、使用 startswith() 和 endswith() 代替切片进行序列前缀或后缀的检查。

  • 6、使用 isinstance() 比较对象的类型,而不是 type(),比如:

# Yes:  
if isinstance(obj, int)

# No:  
if type(obj) is type(1)
  • 7、判断序列是否为空时,不用使用 len() 函数,序列为空时其 bool 值为 False,比如:

# Yes:  
if not seq
if seq

# No:  
if len(seq)
if not len(seq)
  • 8、字符串后面不要有大量拖尾空格。

  • 9、使用 join 合并的字符串,字符串方法 join 可以合并 list、tuple、iterator 中的元素,效率比连接符 + 高。

  • 10、使用 while 1while True 更快。

  • 11、使用 **pow 快 10 倍以上。

  • 12、使用迭代器和生成器代替列表等数据结构效率更高,使用列表(字典)解析式和生成器表达式比用循环效率更高。

  • 13、避免在循环中用 + 或 += 来连续拼接字符串。因为字符串是不变型,这会毫无必要地建立很多临时对象,从而成为二次方级别的运算量而不是线性运算时间。

  • 14、多去了解标准库,标准库中用很多好用的功能,能够更优雅的解决问题,如 pkgutil.get_data()、operator.methodcaller() 等等。


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer