{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 1.6 编码与命名规范"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.6.1 编码规范 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">一般情况下,Python编程遵循<font color=Red>__PEP8规范__</font>,下面仅给出其中一些主要的约定。</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">1. 编码:\n",
"在Python 3中,如无特殊情况, 文件一律使用<font color=Red>__UTF-8 编码__</font>。</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">2. 代码缩进:\n",
"建议使用 <font color=Red>__4 个空格__</font>进行缩进,<font color=Red>__制表符__</font>只能用于与同样使用制表符缩进的代码保持一致。Python 3<font color=Red>__不允许混合使用__</font>空格和制表符的缩进。</font>"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello python\n",
"Hello python\n",
"Hello python\n",
"Hello python\n",
"Hello python\n"
]
}
],
"source": [
"for i in range(5):\n",
" print('Hello python') # 缩进4个空格\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">3. 行的最大长度:\n",
"每行代码尽量少于<font color=Red>__80 个字符__</font> ,在特殊情况下可以超过 80个,但最长不超过 120个。没有结构化限制的大块文本(文档字符或者注释),每行的最大字符数限制在72个。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"\n",
"result = 0\n",
"for i in range(3):\n",
" result = result + ((2 * 2 ** 0.5)) * (math.factorial(4 * i) * (1103 + 26390 * i)) / (math.pow(math.factorial(i), 4) * math.pow(396, 4 * i)) / 9801\n",
"pi = 1 / result\n",
"print(pi)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"超80字符时换行书写:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.141592653589793\n"
]
}
],
"source": [
"import math\n",
"\n",
"result = 0\n",
"for i in range(3):\n",
" result = result + ((2 * 2 ** 0.5)) * (math.factorial(4 * i) * (1103 + 26390 * i)) / (\n",
" math.pow(math.factorial(i), 4) * math.pow(396, 4 * i)) / 9801\n",
"pi = 1 / result\n",
"print(pi)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">4. 引号:\n",
"在Python中,单引号和双引号字符串是相同的。当一个字符串中包含单引号或者双引号字符的时候,使用<font color=Red>__与最外层不同__</font>的符号来<font color=Red>__避免使用反斜杠__</font>,从而提高可读性。\n",
"对于三引号字符串,总是使用双引号字符来与PEP文档字符串约定保持一致。\n",
"<font color=Red>__文档字符串__</font> (docstring) 使用三对双引号 \"\"\"......\"\"\"。</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">用转义字符:\\' 被解析为单引号: ',\\\" 被解析为双引号: \"</font>"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"print('Python is TIOBE\\'s Programming Language of the Year 2021!')\n",
"\n",
"print(\"毛主席说\\\"红军不怕远征难\\\"。\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">推荐用与字符串中引号不同的定界符,避免使用转义字符:</font>"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"print(\"Python is TIOBE's Programming Language of the Year 2021!\")\n",
"\n",
"print('毛主席说\"红军不怕远征难\"。')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">5. 空行:\n",
"模块级函数和类定义之间空两行,类成员函数之间空一行。\n",
"使用多个空行分隔多组相关的函数,函数中可以使用空行分隔出逻辑相关的代码。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def any(*args, **kwargs): # real signature unknown\n",
" \"\"\"Return True if bool(x) is True for any x in the iterable.\"\"\"\n",
" pass\n",
"\n",
"def ascii(*args, **kwargs): # real signature unknown\n",
" \"\"\"Return an ASCII-only representation of an object.\"\"\"\n",
" pass\n",
"\n",
"def bin(*args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ \n",
" \"\"\"Return the binary representation of an integer.\"\"\"\n",
" pass\n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">6. import 语句:\n",
"\n",
"import总是位于文件的<font color=Red>__顶部__</font>,在模块注释和文档字符串之后,在模块的全局变量与常量之前。 \n",
"导入应该按照以下顺序分组: \n",
"1.标准库导入 \n",
"2.相关第三方库导入 \n",
"3.本地应用/库特定导入 \n",
" \n",
"import 语句应该分行书写,在每一组导入之间加入空行。</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"推荐的写法"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的写法\n",
"import turtle\n",
"import math\n",
"from math import sqrt,pow\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"不推荐的写法,一般不建议在同一行内导入多个不同的模块"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 不推荐的写法\n",
"import turtle, math\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">7. 空格: \n",
"(1)在二元运算符+、-、*、/、=、+=、==、>、<、in、is not、and等两边各空一格。</font>"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# 二元符号两端不加空格不属于错误,但不符合规范\n",
"# 以下为格式示例,部分变量未定义,不要运行\n",
"i=i+1\n",
"total=total+i\n",
"area=PI*r**2\n",
"x=(-b+sqrt(b**2-4*a*c))/(2*a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的程序语句写法示例\n",
"i = i + 1\n",
"total = total + i\n",
"area = PI * r ** 2\n",
"x = (-b + sqrt(b ** 2 – 4 * a * c)) / (2 * a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(2)函数的参数列表中,逗号之后要有空格。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的写法\n",
"def complex(real, imag):\n",
" pass\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 不推荐的写法\n",
"def complex(real,imag):\n",
" pass\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(3)左括号之后,右括号之前不要加多余的空格。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的写法\n",
"spam(ham[1], {eggs: 2})\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 不推荐的写法\n",
"spam( ham[1], { eggs : 2 } )\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(4)字典对象的左括号之前不要多余的空格。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的写法\n",
"dict['key'] = list[index]\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#不推荐的写法\n",
"dict ['key'] = list [index]\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(5)不要为对齐赋值语句而使用的额外空格。</font>"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的写法\n",
"x = 5\n",
"y = 10\n",
"long_variable = 20\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# 不推荐的写法\n",
"x = 5\n",
"y = 10\n",
"long_variable = 20\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">8. 换行: \n",
"Python 支持括号内的换行。这时有两种情况: </font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(1) 第二行缩进到左括号的起始处。 "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"wc = WordCloud(font_path = 'msyh.ttc', # 中文字体,须修改路径和字体名\n",
" background_color = 'White',# 设置背景颜色\n",
" max_words = 150, # 设置最大词数\n",
" mask = graph,\n",
" max_font_size = 100, # 设置字体最大值\n",
" random_state = 20, # 设置有多少种随机状态,即配色方案\n",
" scale = 1)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(2)\t第二行缩进 4 个空格,适用于起始括号就换行的情形。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def function_student(\n",
" studentNumber,\n",
" studentName,\n",
" birthdate,\n",
" ):\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(3)\t使用反斜杠“\\”换行 \n",
"一般使二元运算符“+ 、-”等应出现在行末;"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = (-b + math.sqrt(b ** 2 - 4 a c))/(2 * a) + \\\n",
"(-b - math.sqrt(b ** 2 + 4 a b))/(2 * b)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"长字符串也可以用此法换行。"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"print('Hello World!'\\\n",
"'I am Python')\n",
"\n",
"# 代码在两行,输出在一行:Hello World!I am Python"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\"><font color=Red>__禁止复合语句__</font>,即禁止一行中包含多个语句:</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 正确的写法\n",
"\n",
"do_first()\n",
"do_second()\n",
"do_third()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 禁用的写法,不报错,不规范\n",
"\n",
"do_first();do_second();do_third()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 禁用的写法\n",
"a = 50; b = 100; c = 200 # 不报错,可执行,不建议使用\n",
"print(a,b,c) # 50 100 200\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"if/for/while/def等以冒号结尾的语句要<font color=Red>__换行__</font>:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 推荐的写法\n",
"if i == True:\n",
"print('Hello World!')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 不推荐的写法\n",
"if i == True: print('Hello World!')\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"9. 文档注释(docstring) \n",
"文档注释的规范中最基本的两点: \n",
"(1)所有的公共模块、函数、类、方法,都应该写文档注释。私有方法不要求写文档注释,但应该在 def 后提供一个块注释来说明。 \n",
"(2)文档注释的结束\"\"\"应该独占一行,除非此文档注释只有一行。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class _EnumDict(dict):\n",
" \"\"\"\n",
" Track enum member order and ensure member names are not reused.\n",
" EnumMeta will use the names found in self._member_names as the\n",
" enumeration member names.\n",
" \"\"\"\n",
" pass\n",
" ......\n",
"\n",
" def _is_descriptor(obj):\n",
" \"\"\"Returns True if obj is a descriptor, False otherwise.\"\"\"\n",
" pass\n",
" ......\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.6.2 命名规范 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">Python中的命名可以使用<font color=Red>__大(小)写字母__</font>、<font color=Red>__数字__</font>和<font color=Red>__下划线(_)__</font>,数字不做首字母,下划线开头的变量有特殊含义,一般不用。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def f1(a):\n",
" if a % 400 == 0 or a % 100 != 0 and a % 4 == 0: \n",
" return True\n",
" else:\n",
" return False\n",
"\n",
"\n",
"\n",
"def f2(b):\n",
" c = int(b[:4]) \n",
" d = int(b[4:6]) \n",
" e = int(b[-2:]) \n",
" f = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] \n",
" g = sum(f[:d - 1]) + e \n",
" if f1(c) and d >= 2: \n",
" g = g + 1 \n",
" return g \n",
"\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" h = input() \n",
" print(f2(h)) \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def leap(year: int) -> bool:\n",
" \"\"\"接收一个正整数参数,判定该数字对应的年份是否是闰年\n",
" 返回布尔值,是闰年时返回True,不是闰年时返回False\n",
" \"\"\"\n",
" # 年份能被400的整除或年份能被4整除但不能被100整除的是闰年\n",
" if year % 400 == 0 or year % 100 != 0 and year % 4 == 0: # 是闰年时\n",
" return True\n",
" else:\n",
" return False\n",
"\n",
"\n",
"\n",
"def get_days(date_str: str) -> int:\n",
" \"\"\"接收一个表示年月日的整数字符串为参数,返回这个日期是该年的第多少天,返回整数\"\"\"\n",
" year = int(date_str[:4]) # 获取字符串中的年份数值,整数\n",
" month = int(date_str[4:6]) # 获取字符串中的月份数值,整数\n",
" day = int(date_str[-2:]) # 获取字符串中的月份数值,整数\n",
" days_ls = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # 各月天数的列表\n",
" which_day_of_today = sum(days_ls[:month - 1]) + day # 前month-1个月的总天数加当前日期\n",
" if leap(year) and month >= 2: # 若是闰年且月份数大于2\n",
" which_day_of_today = which_day_of_today + 1 # 加上闰年2月多的一天\n",
" return which_day_of_today # 返回是该年的第多少天\n",
"\n",
"\n",
"\n",
"# 以模块模式运行时,执行以下分支中的代码\n",
"if __name__ == '__main__':\n",
" date = input() # 输入一个表示年月日的整数字符串,此处要求输入是合法的年月日数值\n",
" print(get_days(date)) # 输出这个日期是该年第多少天\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(1)类:使用首字母大写单词串,UpperCamelCase,首字母大写的驼峰命名法</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class MyClass():\n",
" pass\n",
" ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(2)函数和方法:小写单词+下划线,lowercase_with_underscores。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def is_prime():\n",
" pass\n",
" ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(3)变量:由下划线连接各个小写字母的单词</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"color = 'red'\n",
"user_name = '李明'\n",
"this_is_a_variable = 10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(4)常量:常量名所有字母大写,由下划线连接各个单词</font>"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"PI = 3.141592653589793\n",
"E = 2.718281828459045\n",
"MAX_OVERFLOW = 1.7976931348623157e+308\n",
"DAYS_OF_YEAR = 365"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(5)异常:以“Error”作为后缀。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 不要运行此单元,只用于显示\n",
"SyntaxError # 语法错误\n",
"NameError # 未声明/未初始化的对象(没有属性)\n",
"SystemError # 一般的解释器系统错误\n",
"ValueError # 传入无效的参数,或传入一个调用者不期望的值,即使值的类型是正确的\n",
"IndentationError # 缩进错误(代码没有正确对齐)\n",
"ImportError # 导入模块/对象失败(路径问题或名称错误)\n",
"ModuleNotFoundError # 模块不存在\n",
"ZeroDivisionError # 除(或取模)零\n",
"OverflowError # 数字运算超出最大限制\n",
"AttributeError #对象没有这个属性\n",
"IndexError # 索引超出序列边界,如x只有10个元素,序号为0-9,程序中却试图访问x[10]\n",
"KeyError # 映射中没有这个键(试图访问字典里不存在的键)\n",
"TypeError # 对类型无效的操作\n",
"TabError # Tab和空格混用\n",
"RuntimeError # 一般的运行时错误"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(6)文件名:全小写,可使用下划线。</font>"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"xrd.csv\n",
"poem.txt\n",
"tang_poem.txt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(7)包与模块:简短的、小写字母的名字。</font>"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"matplotlib\n",
"pandas\n",
"seaborn\n",
"qrcode\n",
"pyplot.py\n",
"algorithms.py"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">命名应当尽量使用完整的单词,缩写的情况有如下两种:</font>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(1)常用的缩写,如XML、ID等,在命名时也应只大写首字母。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"XmlParser\n",
"Id_code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"4\">(2)命名中含有长单词,对某个单词进行缩写。这时应使用约定成俗的缩写方式。</font>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"function 缩写为 fn\n",
"text 缩写为 txt\n",
"object 缩写为 obj\n",
"count 缩写为 cnt\n",
"number 缩写为 num"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"特定命名方式:\n",
"主要是指 xxx 形式的系统保留字命名法。\n",
"项目中也可以使用这种命名,它的意义在于这种形式的变量是只读的,这种形式的类成员函数尽量不要重载。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class Base(object):\n",
" def init(self, id, parent=None):\n",
" self.id = id\n",
" self.parent = parent\n",
"\n",
" def message(self, msgid):\n",
" pass\n",
"\n",
"# 其中 id、parent 和 message 都采用了系统保留字命名法。\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}