如何优雅的编写Python

 一、编程习惯

1、注释

Python中有三种形式的注释:行注释、块注释、文档注释

  1. 行注释:注释应解释自己做了什么,而不是对代码本身的解释
    n = input()
    m = input()
    t = n / 2                    # t是n的一半
    # 循环,条件为t*m/n 小于n
    while (t * m / (n + 1) < n):
        t = 0.5 * m + n / 2      # 重新计算t值
        print(t)
  2. 块注释:
    def FuncName(parameter1,parameter2):
        """
        描述函数要做的事情
        
        :param parameter1: 参数一描述(类型、用途等)
        :param parameter2: 参数二描述
        :return: 返回值描述
        """
  3. 注释和代码隔开一定的距离,块注释后面最好多留几行空白再写代码
  4. 常见的问题:代码不断更新而注释却没有更新;注释比代码本身还复杂烦琐;将别处的注释和代码一起拷贝过来, 但上下文的变更导致注释与代码不同步;想删除某个函数,但是又怕以后会用到,就直接注释掉。

2.命名 

  1. 模块名:模块尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况)
    # 正确
    import decoder
    import html_parser
    
    # 不推荐
    import Decoder

     

  2. 类名:类名使用驼峰(CamelCase)命名风格,首字母大写,私有类可用一个下划线开头
    class Farm():
        pass
    
    class AnimalFarm(Farm):
        pass
    
    class _PrivateFarm(Farm):
        pass

     

  3. 函数:函数名一律小写,如有多个单词,用下划线隔开
    def run():
        pass
    
    def run_with_env():
        pass
    私有函数在函数前加一个下划线_
    class Person():
    
        def _private_func():
            pass

     

  4. 变量名:变量名尽量小写, 如有多个单词,用下划线隔开
    if __name__ == '__main__':
        count = 0
        school_name = ''

     

  5. 常量名:全部大写,如有多个单词,用下划线隔开
    MAX_CLIENT = 100
    MAX_CONNECTION = 1000
    CONNECTION_TIMEOUT = 600

     

需要避免

  • 不要中英文混编
  • 不要有a、b、c这种没有意义的命名
  • 不要怕名字长就随便缩写,比如person_info 缩写成pi
  • 不要用大小写区分变量类型,比如a是int类型,A是String类型
  • 不要使用容易引起混淆的变量名
    def funA(list, num):
        for element in list:
            if num == element:
                return True
            else:
                pass
    
    
    def find_num(searchList, num):
        for listValue in searchList:
            if num == listValue:
                return True
            else:
                pass

     

3.函数设计

函数设计的主要目标就是最大化代码重用和最小化代码冗余。精心设计的函数不仅可以提高程序的健壮性,还可以增强可读性、减少维护成本。

  1. 函数设计要尽量短小,嵌套层次不宜过深。 所谓短小, 就是尽量避免过长函数, 因为这样不需要上下拉动滚动条就能获得整体感观, 而不是来回翻动屏幕去寻找某个变量或者某条逻辑判断等。 函数中需要用到 if、 elif、 while 、 for 等循环语句的地方,尽量不要嵌套过深,最好能控制在3层以内。不然有时候为了弄清楚哪段代码属于内部嵌套, 哪段属于中间层次的嵌套, 哪段属于更外一层的嵌套所花费的时间比读代码细节所用时间更多。
  2. 函数申明应该做到合理、 简单、 易于使用。 除了函数名能够正确反映其大体功能外, 参数的设计也应该简洁明了, 参数个数不宜太多。 参数太多带来的弊端是: 调用者需要花费更多的时间去理解每个参数的意思,测试的时候测试用例编写的难度也会加大
  3.  函数参数设计应该考虑向下兼容。
    # 第一个版本
    def readfile(filename):
        print("file read completed")
    
    readfile("test.txt")
    
    # 第二个版本
    def readfile(filename, logger):
        print("file read completed")
    
    readfile("test.txt", logger)
    
    # 第三个版本
    def readfile(filename, logger=logger.info):
        print("file read completed")
    
    readfile("test.txt")
    应当通过加入默认参数 做到向下兼容。
  4. 一个函数只做一件事。这样有利于代码的重用和测试。

4、其他tips

  1. 二元运算符两侧应有空格,逗号和分号前不需要,在pycharm里,Ctrl+Alt+l可以格式化代码。
  2. 不要在一段代码中说明几件事。 在一组代码表达完一个完整的思路之后, 应该用空白行进行间隔。 如每个函数之间, 导入声明、 变量赋值等。推荐在函数定义或者类定义之间空两行, 在类定义与第一个方法之间, 或者需要进行语义分割的地方空一行。 

二、基本语法

1.充分利用Lazy evaluation的特性

延迟计算(Lazy evaluation ),指的是仅仅在需要执行的时候才会计算表达式的值。

常用实践:

  1. 条件表达式 if x and y,在x为false的时候就不会再计算y的值了, 对于 if x or y ,在x为true的时候就不会再计算y的值了。这样就可以避免不必要的计算,提带来性能上的提升。
  2. 生成器表达式
    def fib():
        a,b=0,1
        while True:
            yield a
            a,b=b,a+b
    
    from itertools import islice
    print(list(islice(fib(),5)))

    因为yield关键字的存在,fib()就不是个普通函数了,fib()被调用的时候会创建一个生成器,islice() 适用于在迭代器和生成器上做切片操作,fib()并不会无限执行,而是执行到yield就暂停掉,所以这样即使while True也不会无限循环,使得无限循环的数据结构成为可能。

  3. 使用enumerate()获取序列迭代的索引和值

    # 方法一
    li = ['a', 'b', 'c']
    for i in range(len(li)):
        print("index:", i, "element:", e)
    
    # 方法二
    li = ['a', 'b', 'c']
    for i, e in enumerate(li):
        print("index:", i, "element:", e)
    
    e = enumerate(li)
    e.next()  # (0,a)
    e.next()  # (1,b)

    对于字典的循环

    for key, value in mydict.iteritems():
        print(key, ":", value)

     

2. ==和is的应用场景

id() 返回的是变量内存

== 的意思就是equal,是判断对象的值是不是相同;

is是对象标识符,它判断两个对象是不是拥有同一块内存。

3.使用else简化代码

  1. 循环语句中的else:如果循环自然走到终点,就会执行else语句,如果被break中断,else语句就不会执行
    #打印素数
    def print_prime(n):
        for i in range(2, n):
            found = True
            for j in range(2, n):
                if i % j == 0:
                    found = False
                    break
            if found:
                print(i)
    
    
    def print_prime1(n):
        for i in range(2, n):
            for j in range(2, n):
                if i % j == 0:
                    break
            else:
                print(i)

     

  2. 异常处理中的else:try块没有抛异常时,执行else。
    def save(db, obj):
        some_error_occurred = False
        try:
            # save attr1
            db.execute(obj.attr1)
            # save attr2
            db.execute(obj.attr2)
        except DBError:
            db.rollback()
            some_error_occurred = True
        if not some_error_occurred:
            db.commit()
    
    
    def save1(db, obj):
        try:
            # save attr1
            db.execute(obj.attr1)
            # save attr2
            db.execute(obj.attr2)
        except DBError:
            db.rollback()
        else:
            db.commit()

     

4.字符串处理 

  1. 连接字符串优先使用join而不是‘+’:join
    str1, str2, str3 = "hello", "world", "!"
    print(str1 + str2 + str3)             #不建议
    print("".join([str1, str2, str3]))    #建议

    join申请内存时,会计算所需要的内存,一次性申请,而‘+’每连接一个字符串都要重新申请一次内存,所以join的效率更高。

  2. 格式化输出
    A = 1.2
    print("输出结果是%f" % A)
    print(f"输出结果是{A}")
    

     

三、推荐资料

  1. 静态代码检查工具pylint
  2. 《流畅的python》、《编写高质量代码 改善Python程序的91个建议》                                                                                  https://pan.baidu.com/s/1j_guw_JCH5po9zPBav4G-A 
    提取码:h9mw 
     

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值