版本 | 日期 | 作者 | 联系 | 备注 |
---|---|---|---|---|
0.1 | 2020-11-30 | 胡乐秋 | 66536382@qq.com | 首次生成 |
bad
def do_anything() -> tuple:
...
good
def _do_anything() -> tuple:
...
bad
DEVICE_TRAITS_DICT = None
def _get_device_traits_dict() -> dict:
"""得到设备特征字典
Returns:
返回{{device_id}: {device_traits_dict}}
"""
global DEVICE_TRAITS_DICT
if not DEVICE_TRAITS_DICT:
DEVICE_TRAITS_DICT = {}
return DEVICE_TRAITS_DICT
good
def _get_device_traits_dict() -> dict:
"""得到设备特征字典
Returns:
返回{{device_id}: {device_traits_dict}}
"""
func, tag_name = (_get_device_traits_dict, '__cache')
if not hasattr(func, tag_name):
setattr(func, tag_name, {})
return getattr(func, tag_name)
显示总比隐式好
bad
from common.utils import * #pylint:disable=wildcard-import, unused-wildcard-import
good
from common.utils import (invoke, dispatch)
- 视图仅负责与用户交互:
- 解析用户输入请求, 获取用户输入参数;
- 根据用户输入参数调用模型, 获取处理结果;
- 渲染模型处理结果, 返回给用户。
- 模型仅负责与数据库交互:
- 检查视图输入参数;
- 根据参数查询、修改数据库;
- 返回处理结果
- 视图不能包含数据库交互: 不能执行SQL, 查询或修改数据库
- 模型不能包含用户交互:不能使用"request"对象
from . import model_welcome as model
@get('/welcome')
@view('/welcome.html')
def _() -> dict:
"""请求欢迎页面
Returns:
返回欢迎页面
"""
# 1. 解析用户输入请求, 获取用户输入参数
user_name_tag, error_tag = ('user_name', 'error')
user_name = request_query_get(user_name_tag)
if not user_name:
return {error_tag: '未指定用户名("{}")参数.'.format(user_name_tag)}
# 2. 根据用户输入参数调用模型, 获取处理结果
success, result_or_error = model.is_valid_user(user_name)
# 3. 渲染模型处理结果, 返回给用户
if not success:
return {error_tag: result_or_error)
return {user_name_tag: user_name_tag}
from common.dbhelper import db_search_record_count
def is_valid_user(user_name: str) -> tuple:
"""是否为有效的用户名
Args:
user_name: 用户名称
Returns:
返回(True, {是否为有效的的用户名: bool})或(False, {error_message})
"""
# 1. 检查视图输入参数
if not user_name:
return (False, '指定用户名参数不能为空.')
# 2.根据参数查询、修改数据库
success, result_or_error = db_search_record_count(...)
# 3. 返回处理结果
if not success:
return (success, result_or_error)
record_count = result_or_error
return (True, record_count > 0)
模型不能使用用户请求对象(request).
bad
model_station.py
def get_user_station_list(request):
...
filter_dict = request_forms_get_record_dict(request)
...
view_station.py
from . import model_station as model
@post('/station_statistcs')
def _() -> str:
...
success, result_or_error = model.get_user_station_list(request)
...
good
model_station.py
def get_user_station_list(filter_dict: dict):
...
view_station.py
from . import model_station as model
@post('/station_statistcs')
def _() -> str:
...
filter_dict = request_forms_get_record_dict(request)
success, result_or_error = model.get_user_station_list(filter_dict)
...
在模型中,推荐定义"R"字符串类。以消除代码中的字符串魔术常量.体现"大范围分布,局部集中"的设计原则.
bad
def _do_something_1(record_dict: dict) -> tuple:
...
record_id, name = map(record_dict.get, ('id', 'name'))
...
def _do_something_2(record_dict: dict) -> tuple:
...
record_id = record_dict.get('id')
...
good
class R:
"""本模块资源"""
ID_TAG, NAME_TAG = ('id',' name')
def _do_something_1(record_dict: dict) -> tuple:
...
record_id, name = map(record_dict.get, (R.ID_TAG, R.NAME_TAG))
...
def _do_something_2(record_dict: dict) -> tuple:
...
record_id = record_dict.get(R.ID_TAG)
...
bad
sql = """SELECT a.concrete_station_sn,
c.name AS contract_name,
d.concrete_name AS concrete_name,
count(*) AS total
FROM tbl_product_info a JOIN tbl_lab b ON a.concrete_station_sn = b.sn
JOIN tbl_party c ON b.contract_sn = c.sn
JOIN tbl_lab d ON a.concrete_station_sn = d.sn
WHERE a.output_datetime like %s {}
group by concrete_station_sn,c.name,d.concrete_name
order by concrete_station_sn,c.name,d.concrete_name"""
good
sql = """SELECT tbl_person.*,
tbl_party.name AS party_name,
cost_statistics.total_cost AS total_cost
FROM tbl_person
LEFT JOIN tbl_party ON tbl_party.sn = tbl_person.party_sn
LEFT JOIN (SELECT account AS account,
SUM(cost) AS total_cost
FROM tbl_cost
GROUP BY account) AS cost_statistics
ON cost_statistics.account = tbl_person.account
WHERE ...
GROUP BY ...
ORDER BY ...
LIMIT ...
OFFSET ..."""
构建动态SQL语句时, 通常需要根据查询参数的数量生成动态占位符.
bad
sn_list = [...]
placeholders = ('%s,' * len(sn_list))[:-1]
sql = """SELECT *
FROM tbl_person
WHERE sn IN ({})""".format(placeholders)
good
sn_list = [...]
placeholders = ', '.join(['%s' for _ in sn_list])
sql = """SELECT *
FROM tbl_person
WHERE sn IN ({})""".format(placeholders)
good: more pythonic
import itertools
sn_list = [...]
placeholders = ','.join(itertools.repeat('%s', len(sn_list)))
sql = """SELECT *
FROM tbl_person
WHERE sn IN ({})""".format(placeholders)
对于仅有一项的容器,增加一个逗号, 表明这是有意行为。
bad
sn_list = ['zs']
sn_tuple = ('zs')
person_dict_list = [{'name': 'zs', 'age': 18}]
good
sn_list = ['zs',]
sn_tuple = ('zs',)
person_dict_list = [{'name': 'zs', 'age': 18},]
有序字典可以使用元组列表初始化
bad
from collections import OrderedDict
field_id_list = ('sn', 'name', 'age', ...)
record_list = [('zs', '张三', 18), ...]
sn_index = field_id_list.index('sn')
result_record_dict = OrderedDict() # {'编号':[记录列表],...}
for record in record_list:
sn_ = record[sn_index]
result_record_dict[sn_] = [value for value in record]
good
from collections import OrderedDict
field_id_list = ('sn', 'name', 'age', ...)
record_list = [('zs', '张三', 18), ...]
sn_index = field_id_list.index('concrete_station_sn')
result_record_dict = OrderedDict([(record[sn_index], list(record)) for record in record_list]) # {'编号':[记录列表],...}
如果出现两个以上的and条件判断, 替换使用"all": 同样支持短路测试.
bad
if record_list and (len(record_list) == 1) and (record_list[0][0] == '*'):
pass
good
if all((record_list, len(record_list) == 1, record_list[0][0] == '*')):
pass
如果出现两个以上的and条件判断, 替换使用"all": 同样支持短路测试.
bad
if condition_1 or condition_2 or condition_3:
pass
good
if any((condition_1, condition_2, condition_3)):
pass
bad
filter_list = []
sql_list = []
value_list = []
...
good
filter_list, sql_list, value_list = ([], [], [])
...
使用字典对象的"setdefault", 简化并使代码"more pythonic".
bad
def add_friend(person_dict: dict, friend_name: str) -> None:
...
friends_tag = 'friends'
if friends_tag not in person_dict:
person_dict[friends_tag] = [friend_name, ]
else:
person_dict[friends_tag].append(friend_name)
good
friends_tag = 'friends'
person_dict.setdefault('friends', []).append(friend_name)
bad
...
sql_list.append('SUM(a.practice_cement) AS practice_cement,')
sql_list.append('SUM(a.practice_water) AS practice_water,')
sql_list.append('SUM(a.practice_sand) AS practice_sand,')
sql_list.append('SUM(a.practice_fine_stone) AS practice_fine_stone,')
sql_list.append('SUM(a.practice_middle_stone) AS practice_middle_stone,')
sql_list.append('SUM(a.practice_coarse_stone) AS practice_coarse_stone,')
sql_list.append('SUM(a.practice_admixture_material) AS practice_admixture_material,')
sql_list.append('SUM(a.practice_additive) AS practice_additive')
sql_list.append('FROM tbl_product_info a')
sql_list.append('LEFT JOIN tbl_lab b ON a.concrete_station_sn = b.sn')
sql_list.append("LEFT JOIN tbl_party c on b.contract_sn = c.sn")
...
good
list(map(sql_list.append, ('SUM(a.practice_cement) AS practice_cement,',
'SUM(a.practice_water) AS practice_water,',
'SUM(a.practice_sand) AS practice_sand,',
'SUM(a.practice_fine_stone) AS practice_fine_stone,',
'SUM(a.practice_middle_stone) AS practice_middle_stone,',
'SUM(a.practice_coarse_stone) AS practice_coarse_stone,',
'SUM(a.practice_admixture_material) AS practice_admixture_material,'
'SUM(a.practice_additive) AS practice_additive',
'FROM tbl_product_info a',
'LEFT JOIN tbl_lab b ON a.concrete_station_sn = b.sn',
"LEFT JOIN tbl_party c on b.contract_sn = c.sn")))
bad
...
for tag in ('cement', 'water', 'sand', 'fine_stone', 'middle_stone', 'coarse_stone', 'admixture_material', 'additive', 'water_cement_ratio', 'water_glue_ratio', 'mix_duration'):
practice_tag = 'practice_%s' % tag
construct_tag = 'construct_%s' % tag
...
good
...
for tag in ('cement', 'water', 'sand', 'fine_stone', 'middle_stone', 'coarse_stone', 'admixture_material', 'additive', 'water_cement_ratio', 'water_glue_ratio', 'mix_duration'):
practice_tag, construct_tag = map('{}_{}'.format, ('practice', 'construct'), (tag, tag))
...
bad
...
for record in record_list:
# 转换sql记录为字典
record_dict = {}
for field_index, field_id in enumerate(field_id_list):
value = record[field_index]
if value:
record_dict[field_id] = value
...
good
...
for record in record_list:
# 转换sql记录为字典
record_dict = {field_id: value for field_id, value in zip(field_id_list, record) if value}
...
a, b = (('a', 'b', 'c', 'd'), (1, 2, 3, 4))
zipped = list(zip(a, b))
assert zipped == [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
c, d = zip(*zipped)
assert a == c and b == d
bad
station_list = [['C1_1', '1标1号拌合站'], ['C1_2', '1标2号拌合站'], ['C2_1', '2标1号拌合站'], ['C2_2', '2标2号拌合站']]
station_sn_list = [x[0] for x in station_list]
station_name_list = [x[1] for x in station_list]
assert station_sn_list == ['C1_1', 'C1_2', 'C2_1', 'C2_2']
assert station_name_list == ['1标1号拌合站', '1标2号拌合站', '2标1号拌合站', '2标2号拌合站']
good
station_list = [['C1_1', '1标1号拌合站'], ['C1_2', '1标2号拌合站'], ['C2_1', '2标1号拌合站'], ['C2_2', '2标2号拌合站']]
station_sn_list, station_name_list = zip(*station_list)
assert station_sn_list == ('C1_1', 'C1_2', 'C2_1', 'C2_2')
assert station_name_list == ('1标1号拌合站', '1标2号拌合站', '2标1号拌合站', '2标2号拌合站')
bad
...
water_tag = 'water'
water = float(record_dict[water_tag]) if water_tag in record_dict else 0
...
good
...
water_tag, default_value = ('water', '0')
water = float(record_dict.get(water_tag, default_value))
...
bad
...
result_render_dict['date_type'] = date_type
result_render_dict['station_sn_list'] = station_sn_list
result_render_dict['station_name_list'] = station_name_list
result_render_dict['default_station_sn'] = station_sn_list[0]
...
good
...
result_render_dict.update({'date_type': date_type,
'station_sn_list': station_sn_list,
'station_name_list': station_name_list,
'default_station_sn': station_sn_list[0]})
...
bad
...
assert record and len(record) > 2
record_id, record_time = record[:2]
...
good
...
assert record and len(record) > 2
record_id, record_time, _ = record
...