2.3 快速掌握Python的基本语法

本节主要讲解Python常用的一些基本语法,便于读者对Python有一个全面的认识。

1.Python官方手册

Python官方手册的下载地址为https://docs.Python.org/3/tutorial/controlflow.html#defining-functions

2.初步理解Python语言

Python是一个强大的面向对象语言,它把编程范式推向了顶峰。它的变量是引用,即实际变量的内存地址。

这意味着Python的函数永远以传址的方式工作(这里使用了一个C/C++术语),当调用一个函数时,并不是复制了一份参数的值来替换占位符,而是把占位符指向了变量本身。这就产生了一个非常重要的结果,可以在函数内部改变这个变量的值。

3.常用数据类型

常用数据类型有列表(list)、元组(tuple)。

4.匿名函数lambda的使用(这是函数式编程的思想)

lambda就是没有名字的函数,简便实用,格式如下。

      def f(x):
        return x+1

这样调用函数是f(4),而下面是使用匿名函数的。

      g =lambda x:x+1

这样使用g(4)。

5.函数式编程的思想

它是继面向对象编程后的编程主流规范,它是一种编程范式,也就是如何编写程序的方法论,属于结构化编程的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。简单来说,就像数学中的公式调用。

案例:表达式为(1 + 2)×3-4。

传统编程代码如下。

      In [1]:a = 1 + 2
      In [2]:b = a * 3
      In [3]:c = b -4
      In [4]:print(c)
      Out[4]:5

函数式编程要求使用函数,可以把运算过程定义为不同的函数,然后写成如下形式。

      In [5]:def add(parm1 , parm2):
                    return parm1 + parm2
      In [6]:def multiply(parm3 , parm4):
                    return parm3 * parm4
      In [7]:def subtract(parm5 , parm6):
                    return parm5- parm6
      In [8]:result = subtract(multiply(add(1,2), 3), 4)
      In [9]:print(result)
      Out[9]:5

6.函数式编程的特点

函数式编程的特点有以下5点。

(1)函数的定位很重要。

(2)只用表达式,不用语句。

· 表达式(Expression)是一个单纯的运算过程,总是有返回值。

· 语句(Statement)是执行某种操作,没有返回值。

函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。产生这种要求的原因是函数式编程的开发动机,一开始就是为了处理运算(Computation),不考虑系统的读写(这就是Spark迭代式计算的一方面)。

语句属于对系统的读写操作,所以就被排斥在外。当然,在实际应用中,不做I/O是不可能的。因此在编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。

(3)没有副作用(这里都是Scala编程的思想)。

所谓“副作用(side effect)”,指的是函数内部与外部互动(最典型的情况就是修改全局变量的值),产生运算以外的其他结果。函数式编程强调没有“副作用”,意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

(4)不修改状态。

函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。在其他类型的语言中,变量往往用来保存状态(state)。不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子就是递归。

(5)引用透明。引用透明指函数的运行不依赖于外部变量或状态,只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。

7.函数式编程使用的意义

(1)代码简洁,方便开发。

(2)接近自然语言,容易理解。

(3)更方便代码管理。

(4)易于“并发编程”。

(5)代码热升级。

8.关于Python可变默认参数的使用

案例:

    def append_to(element, to=[]):
      to.append(element)
      return to

函数应用:

    my_list=append_to(12)
    print my_list
    my_other_list=append_to(42)
    print my_other_list

输出结果:

    [12][12, 42]

修改函数可变默认参数:

    def append_to(element, to=None):
      If to is None:
          to=[]
      to.append(element)
      Return to

输出结果:

    [12][42]

9.关于Python的全局变量定义global

案例1(注意代码的缩进,函数体没有大括号包围):

    def  global_name1():
      global x
      print 'x is ', x
      x=2
      print 'change x is to', x

函数应用:

    x=50
    global_name1()
    print 'change x is to', x

输出结果:

      x is  50
      change x is to 2
      change x is to 2

案例2:

      def  global_name2():
        global x
        print 'x is ', x
        x=2
        print 'change x is to', x

函数应用:

      x=50
      global_name2()
      print 'change x is to', x

输出结果:

      x is  50
      change x is to 2
      change x is to 50

10.查看函数文档

在Python中会经常查看函数方法的文档,其中__doc__为文档字符串,使用方式是函数名.__doc__(注意是两个下画线)。代码如下所示。

      In [1]: import math
      In [2]: math.__doc__
      Out[2]: 'This module is always available. It provides access to
  the\nmathematical functions defined by the C standard.'

11.关于.pyc和.pyo文件的说明

.pyc文件是Python编译后的字节码(Bytecode)文件,可以实现源码隐藏。而.pyo文件是Python编译优化后的字节码文件,针对嵌入式系统,把需要的模块编译成.pyo文件可以减少容量。有一点需要说明:Python并非完全是解释性语言,它是有编译的,先把源码py文件编译成.pyc或者.pyo文件,然后由Python的虚拟机执行。

相对于py文件来说,编译成.pyc文件和.pyo文件本质上和py文件没有太大区别,只是对于这个模块来说加载速度提高了,而并没有提高代码的执行速度。

通常情况下不用主动编译.pyc文件,文档上说只要调用了import model,那么model.py就会先编译成.pyc文件然后加载。

12.关于from ..import ...和import ..的使用区别

如果想直接输入变量名,而不用重复输入函数名,就可以使用from .. import…,案例如下。

· 场景1:from math import sqrt

以后就可以直接输入sqrt这个变量。

· 场景2:from math import *

以后只要是math函数下面的变量,都可以直接输入。

· 场景3:import math as math

应多用这样的方式,这样更加易读,而且避免变量名冲突。

13.关于__name__ = '__main__’的作用及其使用方法

首先注意是两个下画线!有以下两点需要讨论。

(1)脚本模块既可以导入到别的模块中用,也可自己执行。

如果直接执行某个.py文件,那么该文件中“name == 'main’”是true。

如果从另外一个.py文件通过import导入该文件,则__name__的值就是我们这个py文件的名字,而不是__main__。

(2)这个功能还有一个用处:在调试代码时,在“if name == 'main’”中加入一调试代码,可以让外部模块调用时不执行我们的调试代码,但是如果想排查问题的时候,直接执行该模块文件,调试代码能够正常工作。

14.关于dir()函数的使用说明

      In [3]:li = []
      In [4]:dir(li)
      Out [4]:['append', 'count', 'extend', 'index', 'insert', 'pop',
  'remove', 'reverse', 'sort']
      In [5]:d = {}
      In [6]: dir(d)
      Out  [6]:['clear',  'copy',  'get',  'has_key',  'items',  'keys',
  'setdefault']
      In [7]: import odbchelper
      In [8]:dir(odbchelper)
      Out  [8] : ['__builtins__',  '__doc__',  '__file__',  '__name__',
  'buildConnectionString']

解读1:li是一个列表,所以dir(li)返回一个包含所有列表方法的列表。注意返回的列表只包含了字符串形式的方法名称,而不是方法对象本身。

解读2:d是一个字典,所以dir(d)返回字典方法的名称列表。

解读3:odbchelper是一个模块,所以dir(odbchelper) 返回模块中定义的所有部件的列表,包括内置的属性,例如__name__、__doc__,以及其他所定义的属性和方法。

15.关于type()函数和str()函数的使用

type()函数返回任意对象的数据类型。str()将数据强制转换为字符串。每种数据类型都可以强制转换为字符串。

16.关于Python的格式化输出

Python一共有两种格式化输出的方法。

(1)格式表达

      In [9]: '%s %d-%d' % ('hello', 7, 1)
      Out [9]:'hello 7-1'

添加浮点数的精度:

      In [10]: '%.3f' % 1.234567869
      Out [10]:'1.235'

用参数指定浮点数的精度:

      for i in range(5):
            '%.*f' % (i, 1.234234234234234)

输出结果:

      '1'
      '1.2'
      '1.23'
      '1.234'
      '1.2342'

(2)字符串格式化方法调用

      In [11]: '{0} {1}:{2}'.format('hello', '1', '7')
      Out [11]:  'hello 1:7'

用参数指定浮点数的精度:

      In [12]:for i in range(5):
            '{0:.{1}f}'.format(1 / 3.0, i)

输出结果:

      '0'
      '0.3'
      '0.33'
      '0.333'
      '0.3333'

格式化字符串中访问对象属性和字典键值:

      In [13]:'My {1[kind]} runs {0.platform}'.format(sys, {'kind': 'pc'})
      Out [13]:'My pc runs Linux'
      In  [14] : 'My  {map[kind]}  runs  {sys.platform}'.format(sys=sys,
  map={'kind': 'pc'})
      Out [14]:'My pc runs Linux'

在格式化字符串中通过下标(正整数)访问list元素:

    In [15]:somelist = list('SPAM')
    In [16]:'first={0[0]}, third={0[2]}'.format(somelist)
    Out [16]:'first=S, third=A'
    In [17]:'first={0}, last={1}'.format(somelist[1], somelist[-1])
    Out [17]:'first=P, last=M'
    In [18]:parts = somelist[0], somelist[-1], somelist[1:-1]
    In [19]: 'first={0}, last={1}, middle={2}'.format(*parts)
    Out [19]:"first=S, last=M, middle=['P', 'A']"

17.关于Python中json的使用

要在Python中使用json,需要引用json,格式如下。

    import json

18.关于Python中的数学

Python中的nan是一个特殊值的写法,意思就是“not a number”。而对于负数求平方根,如果使用以下代码:

      In [20]:import math
      In [21]:math.sqrt(-1)

则会报错,所以需要使用以下代码:

      In [22]:import cmath
      In [23]:cmath.sqrt(-1)

19.关于Python中的字符串

原始字符串r,用来输入。

      In [24]:print r'Let\'s go! '
      Out [24]:Let\'s go!

不能在原始字符串结尾输入反斜线。换句话说,原始字符串最后的一个字符不能是反斜线,除非对反斜线进行转义。