IT培训网

达内论坛

 找回密码
 立即注册
搜索
查看: 1226|回复: 1

Python编程人员如何写代码更优雅规范

[复制链接]

2052

主题

2251

帖子

7731

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7731
QQ
发表于 2017-7-5 11:56:50 | 显示全部楼层 |阅读模式
  一份优雅、干净、整洁的代码通常自带文档和注释属性,读代码即是读作者的思路。Python 开发中很少要像 Java  一样把遵循某种设计模式作为开发原则来应用到系统中,毕竟设计模式只是一种实现手段而已,代码清晰才是最终目的,而 Python 灵活而不失优雅,这也是为什么  Python 能够深受 geek 喜爱的原因之一。
  代码这样写更优雅,朋友们纷纷表示希望再写点儿,今天就接着这个话题写点 Python 中那些 Pythonic  的写法,希望可以抛砖引玉。
  1、链式比较操作
  age = 18  if age  18 and age  60:      print(young man)  
  pythonic
  if 18  age  60:  print(young man)  
  理解了链式比较操作,那么你应该知道为什么下面这行代码输出的结果是 False。
  False == False == True  False  
  2、if/else 三目运算
  if gender == 'male':      text = '男'  else:      text = '女'  
  pythonic
  text = '男' if gender == 'male' else '女'
  在类C的语言中都支持三目运算 b?x:y,Python之禅有这样一句话:
  "There should be one and preferably only one obvious way to do it. "。
  能够用 if/else 清晰表达逻辑时,就没必要再额外新增一种方式来实现。
  3、真值判断
  检查某个对象是否为真值时,还显示地与 True 和 False 做比较就显得多此一举,不专业
  if attr == True:      do_something()     if len(values) != 0: # 判断列表是否为空      do_something()  
  pythonic
  if attr:      do_something()     if values:      do_something()  
  真假值对照表:

wKiom1lQZkjhXGwQAABCoqJkxSI559.jpg


  4、for/else语句
  for else 是 Python 中特有的语法格式,else 中的代码在 for 循环遍历完所有元素之后执行。
  flagfound = False  for i in mylist:      if i == theflag:          flagfound = True          break      process(i)     if not flagfound:      raise ValueError(List argument missing terminal flag.)  
  pythonic
  for i in mylist:      if i == theflag:          break      process(i)  else:      raise ValueError(List argument missing terminal flag.)  
  5、字符串格式化
  s1 = foofish.net  s2 = vttalk  s3 = welcome to %s and following %s % (s1, s2)  
  pythonic
  s3 = welcome to {blog} and following {wechat}.format(blog=foofish.net, wechat=vttalk)
  很难说用 format 比用 %s 的代码量少,但是 format 更易于理解。
  "Explicit is better than implicit  Zen of Python"
  6、列表切片
  获取列表中的部分元素最先想到的就是用 for 循环根据条件提取元素,这也是其它语言中惯用的手段,而在 Python 中还有强大的切片功能。
  items = range(10)     # 奇数  odd_items = []
  for i in items:      if i % 2 != 0:          odd_items.append(i)     # 拷贝  copy_items = []
  for i in items:      copy_items.append(i)  
  pythonic
  # 第1到第4个元素的范围区间  sub_items = items[1:4]
  # 奇数  odd_items = items[1::2]
  #拷贝  copy_items = items[::]
  或者 items[:]
  列表元素的下标不仅可以用正数表示,还是用负数表示,最后一个元素的位置是 -1,从右往左,依次递减。
  --------------------------  | P | y | t | h | o | n |  --------------------------     0   1   2   3   4   5    -6  -5  -4  -3  -2  -1  --------------------------  
  7、善用生成器
  def fib(n):      a, b = 0, 1      result = []
  while b  n:          result.append(b)          a, b = b, a+b      return result  
  pythonic
  def fib(n):      a, b = 0, 1      while a  n:          yield a          a, b = b, a + b  
  上面是用生成器生成费波那契数列。生成器的好处就是无需一次性把所有元素加载到内存,只有迭代获取元素时才返回该元素,而列表是预先一次性把全部元素加载到了内存。此外用  yield 代码看起来更清晰。
  8、获取字典元素
  d = {'name': 'foo'}  if d.has_key('name'):      print(d['name'])  else:      print('unknown')  
  pythonic
  d.get(name, unknown)
  9、预设字典默认值
  通过 key 分组的时候,不得不每次检查 key 是否已经存在于字典中。
  data = [('foo', 10), ('bar', 20), ('foo', 39), ('bar', 49)]
  groups = {}  for (key, value) in data:      if key in groups:          groups[key].append(value)      else:          groups[key]
  = [value]
  pythonic
  #  第一种方式  groups = {}  for (key, value) in data:      groups.setdefault(key, []).append(value)     # 第二种方式  from collections import defaultdict  groups = defaultdict(list)  for (key, value) in data:      groups[key].append(value)  
  10、字典推导式
  在python2.7之前,构建字典对象一般使用下面这种方式,可读性非常差
  numbers = [1,2,3]
  my_dict = dict([(number,number*2) for number in numbers])  print(my_dict)  # {1: 2, 2: 4, 3: 6}  
  pythonic
  numbers = [1, 2, 3]
  my_dict = {number: number * 2 for number in numbers}  print(my_dict) # {1: 2, 2: 4, 3: 6}  # 还可以指定过滤条件  my_dict = {number: number * 2 for number in numbers if number  1}  print(my_dict) # {2: 4, 3: 6}  
  字典推导式是python2.7新增的特性,可读性增强了很多,类似的还是列表推导式和集合推导式。
 




上一篇:浅析Lambda函数什么时候使用
下一篇:Linux管理员必须掌握的PHP安全要点
回复

使用道具 举报

2052

主题

2251

帖子

7731

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7731
QQ
 楼主| 发表于 2019-9-23 10:06:10 | 显示全部楼层
1. 代码书写要便于阅读。

例如:每行仅书写一条语句(尤其注意 if/for/while 语句)

2. 编码一致性

a. 在同一个项目中的代码要保持一致

b. 在同一个模块中的代码要保持一致

3. 关于缩进:

建议为 4 个空格。若使用 Tab 键,建议将其定义为 4 个空格。

缩进在 python 中是语法相关的,python 解释器通过缩进来判断代码块的从属关系,请谨慎使用

4. 建议代码行最大长度限定为 80 个字符。

当前行未输入完毕,如果继续输入将超过限定长度,此时在当前行尾输入‘\’后再回

车换行(这样 python 解释器认为另起的新行与当前行是同一逻辑行)

5. 代码中输入‘^L’,表示此处分页

6. 编码尽量用 ASCII 码,有特殊需要时可使用 UTF-8 码

7. “import”语句使用规范:

多条“import “语句要分行书写,不建议使用“import A, B”形式。

特殊地,可以使用”from X import A, B” 形式

导入各模块的书写顺序(自上而下):

a. “import 标准内建模块”

b. “import 第三方模块”

c. “import 自建模块”

8. 工程文件目录建在 python 安装目录下

使用”import”语句导入模块时建议使用绝对路径

9. 空行的使用:

类外函数之间: 空 2 行

类内 methods 之间: 空 1 行

各类之间: 空 2 行

10. 空格的使用:

避免在[], (), {}内与括号相接触的位置使用空格,类似[ ‘a’], (‘b’ ), { ‘c’ }等形

式都要避免

双目操作符前后各加一个空格(建议有且仅有一个空格,不建议使用多个或无空格)

特殊地,function 或 method 参数初始化时,‘=’前后都不加空格

11. 关于注释:

注释语言统一为英语

注释用‘# ’开头。(提醒:‘#’后要跟一个空格)

同一注释行中,句子间用两个空格

各注释行间若有空白行,同样以‘#’作行首

若代码本身简单易懂,或命名本身实现了自注释,勿加多余注释

代码修改的同时要修改对应注释,否则危害很大

注释是完整句子时,首单词的首字母大写; 注释较短时可省去末尾的句号

12. 命名规则

保持一致性,至少保持自建代码的一致性

避免使用单个字母做变量,尤其避免’l’, ’o’用作变量

命名字符串不要太长。注:本次会议中,该指标没有量化

类名采用首字母大写的各单词直接相连方式命名。例: “StudentBoy”

非类名采用字母均小写的各单词以下划线相连的方式命名。例:”student_boy”

属内部的 function, class, method 命名要以下划线开。:”_local_time”,“_LocalTime”

异常相关的命名用”Error”或”error”开头

全局变量与 function 命名规则一样

类内默认参数定义为’self’

当对参数命名可能发生重名时,在原名后加下划线作新名。例:”print_”

常量命名采用大写的各单词以下划线相连方式命名。例:”MAX_NAME_LENGTH”
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

IT培训网

QQ|小黑屋|手机版|cnitedu Inc. ( 豫ICP备16023996号-1 )

GMT+8, 2019-10-15 02:33 , Processed in 0.120973 second(s), 9 queries , File On.

Powered by Discuz! X3.3

© 2011-2017 cnitedu Inc.

快速回复 返回顶部 返回列表