91个建议系列之3-让你的代码更加pythonic

注意:这部分内容有些建议你可能并不同意,所以说只是建议,不用据理力争了哈

1、理解python与C的不同之处-建议3

我相信很多同学的入门语言都是C或者C++, 我不得不承认,C确实是很快,笔者曾经报名参加过一个机器学习的比赛,比对的是达到一定准确率以后花费时间,我只用python读取数据就花了4秒,看到那些大神用C已经到毫秒的级别,我便果断放弃了。当然,我这个不是劝退贴,可能我当时的代码优化的好不够好,可能有别的解决办法,希望大家能学得更精通。

事实上Python底层是用C语言实现的,但切忌用C语言的思维和风格来编写Python代码,不要使用其他语言的编程思想。

  • (1)“缩进”与“{}”

    其他语言多使用花括号{}来分隔代码段,Python中使用严格的代码缩进方式分隔代码块,让代码更加规范、整齐,可读性和可维护性都会更高,所以不要瞎敲。很可能带来错误,避免缩进带来的困扰的方法之一就是养成良好的习惯,统一缩进风格,不要混用Tab键和空格。

  • (2)引号的使用

    C中单引号表示一个字符,双引号是字符串,python却没有这么多条条框框,单引号,双引号甚至三引号都可以用来表示字符串,但是需要注意的是,如果字符串中本身出现了引号,就可能需要转义字符:

    str1 = 'He said,"hello"'
    str2 = "He said,\"hello\""
    str3 = '''He said,"hello"'''
    

    不过我打字不好,所以通常只用单引号。三引号通常用于文件头或者函数的大段注释。

  • 三元操作符

    C中存在这三元操作符C ? X: Y,它表示当条件C为True的时候取值X,C为False的时候取值为Y。C ? X: Y在Python 2.5以后的版本中等价的形式为X if C else Y

  • switch··· case···语句

    python中不存在switch语句,不过这也不是必须的,最简单的办法就是用if elif else代替,有些coder也喜欢用跳转表来实现,看起来更加优雅,本质上还是利用了字典的get函数

    def f(x):
        return {
            0: "You typed zero.\n",
            1: "You are in top.\n",
            2: "n is an even number\n"
            }.get(n,  "Only single-digit numbers are allowed\n")
    

    当然除了这些还有很多的不同,写了这么多就是想说,当你准备学习python 的时候,就不要被其他语言的思维和习惯困扰,掌握Python的哲学和思维方式才是硬道理。

2、在代码中添加注释-建议4

Python中有3种形式的代码注释:块注释、行注释以及文档注释(docstring)。当然注释确实你爱咋注释就咋注释,但是有一些不成文的规定,来让你的代码更加美观:

  • (1)使用块或者行注释的时候仅仅注释那些复杂的操作、算法,还有可能别人难以理解的技巧或者不够一目了然的代码。

  • (2)注释和代码隔开一定的距离,同时在块注释之后最好多留几行空白再写代码。比如下面的例子,①比②好。

    x=x+1        # increace x  by 1 ①
    x=x+1 #increase x by 1 ②
    
  • (3)给外部可访问的函数和方法(无论是否简单)添加文档注释。注释要清楚地描述方法的功能,并对参数、返回值以及可能发生的异常进行说明,使得外部调用它的人员仅仅看docstring就能正确使用。较为复杂的内部方法也需要进行注释。推荐的函数注释如下:

    def FuncName(parameter1 , parameter2):
        """Describe what this function does.
            #such as "Find whether the special string is in the queue or not"
            Args:
                parameter1: parameter type, what is this parameter used for.
                            #such as strqueue:string,string queue list for search
                parameter2: parameter type, what is this parameter used for.
                            #such as str:string,string to find
        Returns:
                return type, return value.
                #such as  boolean,sepcial string  found return True,else return False
        """
            function body
            ...
            ...
    
    

    三引号引起来注释部分会被保存在FuncName.__doc__属性中,当使用者需要帮助调用FuncName.__doc__或者help(FuncName)中,会展示这部分内容。所以为了让你的代码被不被人误解,请慎重对待这部分。

  • (4)推荐在文件头中包含copyright申明、模块描述等,如有必要,可以考虑加入作者信息以及变更记录。

    """
      Licensed Materials - Property of CorpA
      (C) Copyright A Corp. 1999, 2011 All Rights Reserved
      CopyRight statement and purpose...
    --------------------------------------------------------------------------
    File Name   : comments.py
    Description : description what the main function of this file
    Author: Author name
    Change Activity:
            list the change activity and time and author information.
    --------------------------------------------------------------------------
    """
    

不过往往有很多程序员因为心态不正,没有认识到注释的重要性,或者注释不得要领,以下是一些例子:

  • (1)不写注释,这个肯定是不对的

  • (2)注释与代码重复。注释应该是用来解释代码的功能、原因以及想法的,而不是对代码本身的解释。

  • (3)利用注释语法快速删除代码。对于不再需要的代码,应该将其删除,而不是将其注释掉。

  • (4)代码经常更新,注释雷打不动。

  • (5)注释比代码还复杂。

  • (6)注释用来自己行乐。这个我也摆脱不了,哈哈

    。。。

3、适当添加空行-建议5

延续上一小节内容,还是要摆正态度:

代码不是恒定的,只有风格才能延续,能工作的代码和整洁、优雅的格式同样重要。

尽管没有强制要求,但是仍然有一些基本规则需要遵守

  • (1)在一组代码表达完一个完整的思路之后,应该用空白行进行间隔。如每个函数之间,导入声明、变量赋值等。

  • (2)如当一个函数需要调用另一个函数的时候,尽量将它们放在一起,最好调用者在上,被调用者在下。

  • (3)避免过长的代码行,每行最好不要超过80个字符。代码换行 可以采用\进行说明,如果是{}、[]、()中的换行,可以在一个元素完成以后直接换行。

  • (4)不要在一行有多个命令,如不要将X=1;Y=2;直接写在一行中。导入每次导入一个就行,不要一次导入好多

4、编写函数的4个原则-建议6

函数能够带来最大化的代码重用和最小化的代码冗余。一般来说函数设计有以下基本原则可以参考:

  • 原则1 函数设计要尽量短小,嵌套层次不宜过深。不要翻了好几页屏幕找变量,if for这些3次就很深了,不要再往下嵌套了!

  • 原则2 函数参数设计应该考虑向下兼容。当你在更新函数时,应考虑到别的程序可能用的老函数,一动这个函数,原有程序可能就会报错。尤其对应于函数的输入输出,不要随意更改。

  • 原则3 一个函数只做一件事,尽量保证函数语句粒度的一致性。

  • 原则4 不要在函数中定义可变对象作为默认值。如果不理解不用担心,后续我们会继续对这部分进行说明。例如下面的简单例子:

    def add_list(alist, added=[]):
        '''将两个列表拼接起来'''
        added += alist
        return added
    
    print(add_list([5]))
    print(add_list([2]))
    
    # 输出
    [5]
    [5, 2]
    

当第一次拼接的时候,由于没有added,所以使用默认的空列表,结果为[5]没有问题,但是当第二次调用时,应该返回[2],但实际返回[5, 2]。根本原因是默认参数在函数被调用的时候仅仅被评估一次,以后都会使用第一次评估的结果。因此实际上对象空间里面缺省值如果是常数,则每次调用该常数;如果缺省值是变量(比如列表),每次调用都会将缺省值初始化为该列表。如果第一次调用的时候缺省列表发生变化,在第二次调用时,初始化会读取已变化的列表地址。对于这种情况,建议采用不可变序列或者直接赋值为None。这部分在内容在后面还会涉及,以及流畅的python版块中也有对应的描述。

5、常量集中到一个文件中-建议7

约定俗成的,python中的常量名所有字母大写,用下划线连接各个单词,如MAX_OVERFLOW、TOTAL,但是这只是一种代码风格,后续仍然可以更改这些常量的值。

为了保证常量必须字母大写以及不可修改,常用的方法是将存放常量的文件命名为constant.py,并在其中定义一系列常量:

class _const:
    class ConstError(TypeError):
        pass

    class ConstCaseError(ConstError):
        pass

    def __setattr__(self, name, value):
        """设置属性时会调用此方法,详情可见我的另一篇博客https://blog.csdn.net/Murphy_31/article/details/105342818"""
        if name in self.__dict__:   # 变量名存在禁止修改
            raise self.ConstError
        if not name.isupper(): # 变量名不是全大写报错
            raise self.ConstCaseError
        self.__dict__[name] = value # 满足两个条件可以添加常量


const= _const()
const.PI = 3.14
const.E = 2.71

当在其他模块中引用这些常量时,按照如下方式进行即可:

from constant import const
const.PI

——End——
欢迎关注我的微信公众号
扫码关注公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值