Python代码规范整理

2022-01-22  本文已影响0人  LegendGo

通用类

I. 代码实现

1.1 加密算法

1.1.1【必须】避免使用不安全的对称加密算法

1.2 程序日志

1.2.1 【建议】对每个重要行为都记录日志

1.2.2 【建议】禁止将未经验证的用户输入直接记录日志

1.2.3 【建议】避免在日志中保存敏感信息

1.3 系统口令

1.3.1【必须】禁止使用空口令、弱口令、已泄露口令

1.3.2 【必须】口令强度要求

口令强度须同时满足:

  1. 密码长度大于14位
  1. 必须包含下列元素:大小写英文字母、数字、特殊字符
  1. 不得使用各系统、程序的默认初始密码
  1. 不能与最近6次使用过的密码重复
  1. 不得与其他外部系统使用相同的密码

1.3.3 【必须】口令存储安全

1.3.4【必须】禁止传递明文口令

1.3.5 【必须】禁止在不安全的信道中传输口令

II. 配置&环境

2.1 Python版本选择

2.1.1【建议】使用Python 3.6+的版本

为什么要这么做? 由于 Python 2 在 2020 年停止维护,相关组件的漏洞不能得到及时修复与维护

2.2 第三方包安全

2.2.2 【必须】禁止使用不安全的组件

2.3 配置信息

2.3.1 【必须】密钥存储安全

2.3.2【必须】禁止硬编码敏感配置

后台类

I. 代码实现

1.1 输入验证

1.1.1【必须】按类型进行数据校验

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n84" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># Cerberus示例
v = Validator({'name': {'type': 'string'}})
v.validate({'name': 'john doe'})

jsonschema示例

schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
"name" : {"type" : "string"},
},
}

validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)</pre>

1.2 SQL操作

1.2.1 【必须】使用参数化查询

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n90" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 错误示例
import mysql.connector

mydb = mysql.connector.connect(
... ...
)

cur = mydb.cursor()
userid = get_id_from_user()

使用%直接格式化字符串拼接SQL语句

cur.execute("SELECT id, password FROM auth_user WHERE id=%s " % (userid,))
myresult = cur.fetchall()</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n91" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 安全示例
import mysql.connector

mydb = mysql.connector.connect(
... ...
)
cur = mydb.cursor()
userid = get_id_from_user()

将元组以参数的形式传入

cur.execute("SELECT id, password FROM auth_user WHERE id=%s " , (userid,))
myresult = cur.fetchall()</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n95" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 安装sqlalchemy并初始化数据库连接

pip install sqlalchemy

from sqlalchemy import create_engine

初始化数据库连接,修改为你的数据库用户名和密码

engine = create_engine('mysql+mysqlconnector://user:password@host:port/DATABASE')</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n96" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 引用数据类型
from sqlalchemy import Column, String, Integer, Float
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

定义 Player 对象:

class Player(Base):

表的名字:

tablename = 'player'

表的结构:

player_id = Column(Integer, primary_key=True, autoincrement=True)
team_id = Column(Integer)
player_name = Column(String(255))
height = Column(Float(3, 2))</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n97" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 增删改查
from sqlalchemy.orm import sessionmaker

创建 DBSession 类型:

DBSession = sessionmaker(bind=engine)

创建 session 对象:

session = DBSession()

增:

new_player = Player(team_id=101, player_name="Tom", height=1.98)
session.add(new_player)

删:

row = session.query(Player).filter(Player.player_name=="Tom").first()
session.delete(row)

改:

row = session.query(Player).filter(Player.player_name=="Tom").first()
row.height = 1.99

查:

rows = session.query(Player).filter(Player.height >= 1.88).all()

提交即保存到数据库:

session.commit()

关闭 session:

session.close()</pre>

1.2.2 【必须】对参数进行过滤

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n102" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">def sql_filter(sql, max_length=20):
dirty_stuff = [""", "\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+",
"&", "$", "(", ")", "%", "@", ","]
for stuff in dirty_stuff:
sql = sql.replace(stuff, "x")
return sql[:max_length]</pre>

1.3 执行命令

1.3.1【建议】避免直接调用函数执行系统命令

1.3.2【必须】过滤传入命令执行函数的字符

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n114" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">import os
import sys
import shlex

domain = sys.argv[1]

替换可以用来注入命令的字符为空

badchars = "\n&;|'"$()`-"
for char in badchars:
domain = domain.replace(char, " ")

result = os.system("nslookup " + shlex.quote(domain))</pre>

1.4 XML读写

1.4.1 【必须】禁用外部实体的方法

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n120" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">from lxml import etree

xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))</pre>

1.5 文件操作

1.5.1【必须】文件类型限制

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n126" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">import os

ALLOWED_EXTENSIONS = ['txt','jpg','png']

def allowed_file(filename):
if ('.' in filename and
'..' not in filename and
os.path.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS):

return filename
return None</pre>

1.5.2 【必须】禁止外部文件存储于可执行目录

1.5.3 【必须】避免路径穿越

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n136" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">import os

upload_dir = '/tmp/upload/' # 预期的上传目录
file_name = '../../etc/hosts' # 用户传入的文件名
absolute_path = os.path.join(upload_dir, file_name) # /tmp/upload/../../etc/hosts
normalized_path = os.path.normpath(absolute_path) # /etc/hosts
if not normalized_path.startswith(upload_dir): # 检查最终路径是否在预期的上传目录中
raise IOError()</pre>

1.5.4 【建议】避免路径拼接

1.5.5 【建议】文件名hash化处理

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n146" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">import uuid

def random_filename(filename):
ext = os.path.splitext(filename)[1]
new_filename = uuid.uuid4().hex + ext
return new_filename</pre>

1.6 网络请求

1.6.1 【必须】限定访问网络资源地址范围

当程序需要从用户指定的URL地址获取网页文本内容加载指定地址的图片进行下载等操作时,需要对URL地址进行安全校验:

  1. 只允许HTTP或HTTPS协议

  2. 解析目标URL,获取其host

  3. 解析host,获取host指向的IP地址转换成long型

  4. 检查IP地址是否为内网IP

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n159" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 以RFC定义的专有网络为例,如有自定义私有网段亦应加入禁止访问列表。
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
127.0.0.0/8</pre>

  1. 请求URL

  2. 如果有跳转,跳转后执行1,否则对URL发起请求

1.7 响应输出

1.7.1【必须】设置正确的HTTP响应包类型

响应包的HTTP头“Content-Type”必须正确配置响应包的类型,禁止非HTML类型的响应包设置为“text/html”。

1.7.2【必须】设置安全的HTTP响应头

1.7.3【必须】对外输出页面包含第三方数据时须进行编码处理

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n182" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 推荐使用mozilla维护的bleach库来进行过滤
import bleach
bleach.clean('an <script>evil()</script> example')

u'an <script>evil()</script> example'</pre>

1.8 数据输出

1.8.1【必须】敏感数据加密存储

1.8.2【必须】敏感信息必须由后台进行脱敏处理

1.8.3【必须】高敏感信息禁止存储、展示

1.8.4【必须】个人敏感信息脱敏展示

在满足业务需求的情况下,个人敏感信息需脱敏展示,如:

1.8.5【必须】隐藏后台地址

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n218" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 不要采取这种方式
admin_login_url = "xxxx/login"</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n219" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python"># 安全示例
admin_login_url = "xxxx/ranD0Str"</pre>

1.9 权限管理

1.9.1【必须】默认鉴权

1.9.2【必须】授权遵循最小权限原则

1.9.3【必须】避免越权访问

  1. 验证当前用户的登录态;

  2. 从可信结构中获取经过校验的当前请求账号的身份信息(如:session),禁止从用户请求参数或Cookie中获取外部传入不可信用户身份直接进行查询;

  3. 校验当前用户是否具备该操作权限;

  4. 校验当前用户是否具备所操作数据的权限;

  5. 校验当前操作是否账户是否预期账户。

1.9.4【建议】及时清理不需要的权限

1.10 异常处理

1.10.1【必须】不向对外错误提示

1.10.2 【必须】禁止异常抛出敏感信息

1.11 Flask安全

1.11.1【必须】生产环境关闭调试模式

1.11.2【建议】遵循Flask安全规范

1.12 Django安全

1.12.1【必须】生产环境关闭调试模式

1.12.2【建议】保持Django自带的安全特性开启

1.12 代码注释

注释虽然写起来很痛苦, 但对保证代码可读性至关重要. 下面的规则描述了如何注释以及在哪儿注释. 当然也要记住: 注释固然很重要, 但最好的代码应当本身就是文档. 有意义的类型名和变量名, 要远胜过要用注释解释的含糊不清的名字.

你写的注释是给代码读者看的, 也就是下一个需要理解你的代码的人. 所以慷慨些吧, 下一个读者可能就是你!

1.12.1 注释风格

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n297" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="">"""
"""块注释

行注释</pre>

1.12.2 类注释

每个类的定义都要附带一份注释, 描述类的功能和用法, 除非它的功能相当明显.

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n303" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">
class Hello():
"""
Test case
"""</pre>

类注释应当为读者理解如何使用与何时使用类提供足够的信息, 同时应当提醒读者在正确使用此类时应当考虑的因素. 如果类有任何同步前提, 请用文档说明. 如果该类的实例可被多线程访问, 要特别注意文档说明多线程环境下相关的规则和常量使用.

如果你想用一小段代码演示这个类的基本用法或通常用法, 放在类注释里也非常合适.

1.12.3 函数注释

函数注释分为两块,一个是函数声明,一个是函数定义

1.12.4 变量注释

1.12.5 实现注释

对于代码中巧妙,晦涩,有趣的地方需要加上注释

1.12.6 不允许的行为

注释里不建议描述一些显而易见的代码逻辑,永远不愿用自然语言将代码翻译过来作为注释,所提供的注释更应该是描述为什么这么做,以及业务逻辑

1.12.7 TODO注释

TODO常用于下面的场景

1.12.8 弃用注释

通过弃用注释(DEPRECATED comments)以标记某接口/函数点已弃用,可以在注释中说明弃用的原因。

II. 风格规范

2.1 类型注释

python 在3.0以后的版本中引入了类型说明

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n441" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">class Hello(mm:str,nn:list):
pass
</pre>

通用规则

格式说明

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n475" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">def my_method(self,first_var:str,
second_var:str):
pass</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" cid="n484" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background-color: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit; caret-color: rgb(184, 191, 198); color: rgb(184, 191, 198); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" lang="python">class MyClass:
def init(self,stack:list["mysl"]) -> None:
pass</pre>

上一篇 下一篇

猜你喜欢

热点阅读