이 글은 Python 코딩 형식에 대한 자세한 소개를 제공합니다(예제 포함). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
코드는 실행 외에도 읽기에도 사용됩니다. 코드를 더 읽기 쉽게 만들기 위해 많은 프로그래밍 언어에는 자체 코딩 표준이 있습니다. 사양은 코드 일관성을 유지하여 코드를 더욱 아름답고 읽기 쉽게 만들기 위해 개발되었습니다. 코드의 형식을 지정하고 작성하는 방법은 절대적인 것이 아니므로 일부 영역에서는 논란의 여지가 있습니다. 스타일 가이드가 적용되지 않는 경우도 있으며, 가장 중요한 것은 언제 일관성을 유지해야 하는지 아는 것입니다. 무엇을 해야 할지 잘 모르겠으면 다른 예를 살펴봐야 합니다.
이 글은 Python 코딩 스타일에 대한 참고자료일 뿐 반드시 이런 식으로 해야 한다는 규칙은 아닙니다. 이 문서의 목적은 개발자가 더 읽기 쉬운 코드를 작성하도록 안내하는 가이드 역할을 하는 것입니다.
1. 코드 레이아웃
주로 들여쓰기와 빈 줄의 레이아웃:
1 들여쓰기에는 공백 4개를 사용합니다. (편집자는 이 기능을 완료할 수 있습니다.) 탭 문자를 혼합하여 사용할 수 없습니다. 탭과 공백.
2. 각 줄은 80자를 초과할 수 없습니다. 줄바꿈에 백슬래시를 사용할 수 있으며, 괄호를 사용하는 것이 가장 좋습니다(Python은 암시적으로 괄호, 대괄호 및 중괄호로 줄을 연결합니다).
3. 클래스와 최상위 함수 정의 사이에는 두 개의 빈 줄이 있습니다. 클래스의 메서드 정의 사이에는 한 개의 빈 줄이 있으며, 함수 내에서 논리적으로 관련 없는 단락 사이에는 빈 줄이 없습니다.
1 모듈 내용의 순서: 모듈 설명, 모듈 문서 문자열, import 문, 전역 변수 또는 상수, 기타 정의.
2. 모듈 가져오기 부분 순서: 표준 라이브러리, 타사 모듈, 사용자 정의 모듈 각 부분 사이에 빈 줄이 있습니다.
3. 하나의 import 문에서 한 번에 여러 모듈을 가져오지 마세요. import os, sys
는 권장되지 않습니다. import os, sys
不推荐。
4、导入模块时应该使用合适的方式来避免命名冲突,例如在适当的时候才使用 from xx import xx
,尽量避免使用 from xx imoprt *
。
5、在自已编写的模块中,如果需要使用 from xx import *
时,应该在导入语句后或者模块尾使用 __all__
机制来限制导入规则。
1、通常每个语句应该独占一行。
2、不要在行尾加分号, 也不要用分号将多条语句放在同一行。
3、if/for/while 语句中,即使执行语句只有一句,也应尽量另起一行。
4、不要在返回语句(return)或条件语句(if/for/while)中使用括号,除非是用于实现行连接。
5、对于 if 语句, 在没有 else 且语句比较短时,可以在一行完成(但不推荐),比如:if foo: bar(foo)
.
6、对于简单的类定义,也可以在一行完成(但不推荐),比如定义一个异常:class UnfoundError(Exception): pass
.
7、函数和方法的括号中使用垂直隐式缩进或使用悬挂缩进。
# 一行写不下时,有括号来连接多行,后续行应该使用悬挂缩进 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', )
总体原则,避免不必要的空格。
1、各种右括号前不要加空格。
2、逗号、冒号、分号前不要加空格,但应该在它们后面加(除了在行尾)。
3、函数的左括号前不要加空格。如 Func(1)。
4、序列的左括号前不要加空格。如 list[2]。
5、操作符左右各加一个空格,不要为了对齐增加空格。
6、函数默认参数使用的赋值符左右省略空格。
良好的风格:
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)
不好的风格:
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)
总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释。注释尽量使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。如果是短语,可以省略结束符。注释应该在 #
from xx import xx
를 사용하고 from xx imoprt는 사용하지 마세요. * 코드>. <p></p>
from xx import *
를 사용해야 하는 경우 import 문 뒤나 위치에서 __all__
메커니즘을 사용해야 합니다. 가져오기 규칙을 제한하려면 모듈을 종료하세요. class UnfoundError(Exception): pass
.🎜 🎜🎜🎜7. 함수 및 메서드에 대한 괄호는 세로 암시적 들여쓰기 또는 내어쓰기를 사용합니다. 🎜🎜🎜# Description : Module config. # # Input : None # # Output : None
person = { "name": "huoty", # 姓名 "age": 26, # 年龄 "stature": 169, # 身高 "weight": 60, # 体重 } print person # 输出信息
# TODO(sudohuoty@gmail.com): Use a "*" here for string repetition. # TODO(Huoty) Change this to use relations.
#
뒤에 공백으로 시작해야 합니다. 🎜🎜🎜🎜1. 블록 주석은 코드 앞에 추가되는 주석입니다. 단락 사이에 '#'만 있는 줄을 사용하세요. 예: 🎜🎜🎜# 你可能会认为你读得懂以下的代码。但是你不会懂的,相信我吧。 # 要是你尝试玩弄这段代码的话,你将会在无尽的通宵中不断地咒骂自己为什么会认为自己聪明到可以优化这段代码。 # 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
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 1
比 while True
更快。
11、使用 **
比 pow
快 10 倍以上。
12、使用迭代器和生成器代替列表等数据结构效率更高,使用列表(字典)解析式和生成器表达式比用循环效率更高。
13、避免在循环中用 + 或 += 来连续拼接字符串。因为字符串是不变型,这会毫无必要地建立很多临时对象,从而成为二次方级别的运算量而不是线性运算时间。
14、多去了解标准库,标准库中用很多好用的功能,能够更优雅的解决问题,如 pkgutil.get_data()、operator.methodcaller() 等等。
위 내용은 Python 코딩 형식에 대한 자세한 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!