• 《python基础教程》要点(六):抽象


    (一)创建函数:

    1、内建的callable函数可以用来判断函数是否可调用:

    (Python 2.7.4)

    1 >>> import math
    2 >>> x = 1
    3 >>> y = math.sqrt
    4 >>> callable(x)
    5 False
    6 >>> callable(y)
    7 True

    【注意】函数callable在Python 3.0中不再可用,需要使用表达式hasattr(func._call_)代替。有关hasattr更多信息,参见第7章。

    2、使用def(或“函数定义”)语句创建函数:

    如:返回斐波那契数列的函数:

     1 >>> def fibs(num):
     2     result = [0,1]
     3     for i in range(num - 2):
     4         result.append(result[-2] + result[-1])
     5     return result
     6 
     7 >>> fibs(10)
     8 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
     9 >>> fibs(5)
    10 [0, 1, 1, 2, 3]
    11 >>> 

    3、记录函数:在函数开头写下字符串,它会作为函数的一部分进行存储,这称为文档字符串

    文档字符串可以按输入myfuction._doc_方式访问,但是读者发现在Python 2.7.4只有myfuction.func_doc能行:

     1  def myf():
     2     'i want this function return two character showing welcome'
     3     return "你好"
     4 
     5 >>> print myf()
     6 你好
     7 >>> myf._doc_
     8 
     9 Traceback (most recent call last):
    10   File "<pyshell#21>", line 1, in <module>
    11     myf._doc_
    12 AttributeError: 'function' object has no attribute '_doc_'
    13 >>> myf.func_doc
    14 'i want this function return two character showing welcome'
    15 >>> 

     【注意】_doc_是函数属性,详细看第7章。属性名下的双划线表示它是个特殊属性,详细看第9章。

    4、内建help函数,在交互式解释器中使用,就可以得到关于函数、包括它的文档字符串的信息:

    1 >>> def myf():
    2      'i want this function return two character showing welcome'
    3      return "你好"
    4 
    5 >>> help(myf)
    6 Help on function myf in module __main__:
    7 
    8 myf()
    9     i want this function return two character showing welcome
    1 >>> import math
    2 >>> help(math.sqrt)
    3 Help on built-in function sqrt in module math:
    4 
    5 sqrt(...)
    6     sqrt(x)
    7     
    8     Return the square root of x.

    (二)参数魔法

    1、在函数内为参数赋予新值不会改变外部任何变量的值。

    【注意】参数存储在局部作用域(local scope)内。

     2、字符串(以及数字元组)是不可变的,即无法被修改(也就是说,只能用新的值覆盖)。所以它们做参数的时候也就无需多做介绍。

      但是如果将可变的数据结构,如列表,作为参数的时候,会发生:参数被改变了。

     1 >>> names = ['aaa','bbb']
     2 >>> n = names
     3 >>> n[0] = 'new'
     4 >>> names
     5 ['new', 'bbb']
    6 >>> names2 = ['aaa','bbb'] 7 >>> n2 = names2[:] 8 >>> #现在n2和names2包含两个独立(不同)的列表,其值相等: 9 >>> n2 is names2 10 False 11 >>> n2 == names2 12 True 13 >>> #如果现在改变n2,就不会影响到names2了: 14 >>> n2[0] = 'new' 15 >>> n2 16 ['new', 'bbb'] 17 >>> names2 18 ['aaa', 'bbb']


    3、初始化数据结构的函数:

     1 >>> def init(data):  #把初始化代码放到函数中
     2     data['first'] = {}
     3     data['middle'] = {}
     4     data['last'] = {}
     5 
     6     
     7 >>> #使用:
     8 >>> s = {}
     9 >>> init(s)
    10 >>> s
    11 {'middle': {}, 'last': {}, 'first': {}}

     【注意】字典的键并没有具体顺序,每次在解释器中打印的顺序可能不同。

    4、如果参数不可变,比如数字,想要改变值,只能从函数中返回你要的值了(多的话用元组返回):

    1 >>> def addself(x):
    2     return x + 1
    3 
    4 >>> y = 1
    5 >>> y = addself(y) #赋值为使用addself函数后返回的值
    6 >>> y
    7 2

    小技巧】如果真想改变参数,那么可以将值放在在列表中:

    1 >>> def addself(x): #无需返回值哦
    2     x[0] = x[0] + 1
    3 
    4     
    5 >>> y = [1]      #将值放在列表中
    6 >>> addself(y)   #这样代码看起来比较清新
    7 >>> y
    8 [2] 

     5、关键字参数和默认值

    目前为止我们使用的参数都叫位置参数

    关键字参数:可以明确每个参数的作用,避免参数多的时候很难记住参数的顺序。

    1 >>> def myf(greet,name):
    2     print "%s,%s" % (greet,name)
    3 
    4     
    5 >>> myf('hello','lisa')
    6 hello,lisa
    7 >>> myf(greet = 'hi',name = 'linda')
    8 hi,linda

    最厉害的是,可以在函数中给参数提供默认值。如果参数具有默认值,调用的时候,你可以不提供参数、提供一些或提供所有。

     1 >>> def wel(greet = 'what',name = 'who'):
     2     print '%s,%s' % (greet,name)
     3 
     4     
     5 >>> wel()
     6 what,who
     7 >>> wel(name = 'Elizabeth')
     8 what,Elizabeth
     9 >>> wel('hah')
    10 hah,who

    位置参数和关键字参数可以联合使用,但要把位置参数放在前面。不然,解释器会不知道它们到底谁是谁(也就是它们应该处的位置)。

    【注意】除非完全清楚程序的功能和参数的意义,否则避免混合使用位置参数和关键字参数。

    6、收集参数

    让用户提供任意数量的参数。

    *:参数前的星号将所有值放在同一个元组中,如果有普通参数在前,星号的意思就是“收集其余位置的参数”(除了关键字的参数)。

    **:处理关键字参数的“收集”操作。放在字典里,而不是元组。

     1 >>> def print_params(x,y,z = 3,*pospar,**keypar):
     2     print x,y,z
     3     print pospar
     4     print keypar
     5 
     6     
     7 >>> print_params(1,2,3,7,8,9,foo = 1,bar = 2)
     8 1 2 3
     9 (7, 8, 9)
    10 {'foo': 1, 'bar': 2}

    7、反转过程

    使用*和**可以收集参数,放进元组和字典里,供函数使用。也可以执行相反的操作,将收集好的元组或字典里的参数通过*或**传进函数。

    【注意】operator模块中包含此函数的效率更高版本。

    使用*:

    1 >>> def add(x,y):
    2     return x + y
    3 
    4 >>> params = (1,2)
    5 >>> add(*params)
    6 3

     使用**:

    1 >>> def hello(name,sex):
    2     print name + ' is a '+ sex
    3 
    4 >>> params = {'name':'one','sex':'girl'}    
    5 >>> hello(**params)
    6 one is a girl

    星号只在定义函数(允许使用不定数目的参数)或者调用“分隔”字典或序列时才有用:

     1 >>> def wit(**k):    #在定义中使用星号
     2     print k['name'],' is',k['age'],' years old.'
     3 
     4     
     5 >>> def nwit(k):     #在定义中不使用星号
     6     print k['name'],' is',k['age'],' years old.'
     7 
     8     
     9 >>> args = {'name':'one','age':'36'}
    10 >>> wit(**args)      #在使用中使用星号
    11 one  is 36  years old.
    12 >>> nwit(args)       #在使用中不使用星号
    13 one  is 36  years old.
    14 >>>                  #效果一样

    (三)作用域

    1、在执行 x = 1 后,名称 x 引用到值 1 。就像字典一样。当然,变量和所对应的值用的是个“不可见”的字典,叫做命名空间或者作用域。内建的vars函数可以返回这个作用域:

    1 >>> x = 1
    2 >>> scope = vars()
    3 >>> scope['x']
    4 1
    5 >>> scope['x'] += 1
    6 >>> x
    7 2

    每个函数调用都会创建一个新的作用域。

    函数内的变量被称为局部变量(local variable)。

    1 >>> def myf():
    2     x = 32
    3 
    4     
    5 >>> x = 1
    6 >>> myf()
    7 >>> x
    8 1

    这里 myf函数改变(重绑定)了变量 x ,但是调用myf的时候创建了新的命名空间,x = 32只在内部作用域(局部命名空间)其作用,没有影响到全局作用域的x。

    屏蔽(Shadowing)的问题

    同名的话,全局变量会被局部变量屏蔽,但是可以使用globals函数获取全局变量值,该函数的近亲是vars,它可以返回全局变量的字典:

    1 >>> param = "哈哈"
    2 >>> def myf(param):
    3     print param + globals()['param']
    4 
    5     
    6 >>> myf('paramfrommyf')
    7 paramfrommyf哈哈

    使用globals函数,重绑定全局变量(使变量引用其他新值):

    1 >>> x = 1
    2 >>> def change():
    3     global x
    4     x = x+1
    5 
    6     
    7 >>> change()
    8 >>> x
    9 2

    2、嵌套作用域

    突出应用是,例如需要用一个函数“创建”另一个。详细见105页,不常用吧。

    (四)递归

    1、recursion:see recursion.

    有用的递归函数包含:

    (1)当函数直接返回值时有基本实例(最小可能性问题)。

    (2)递归实例,包括一个或者多个问题最小部分的递归调用。

    关键就是将问题分解为小部分。

    经典应用:阶乘、幂、二分查找。

    2、函数到处放

    Python对“函数式编程”方面有一些有用的函数:map、filter和reduce函数(Python3.0中这些都被移至functools模块中)。filter函数可以基于一个返回布尔值的函数都会元素进行过滤。

    1 >>> map(str,range(10))
    2 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    1 >>> def func(x):
    2     return x.isalnum()
    3 
    4 >>> seq = ['aaa','x35','?!','***','&%$#']
    5 >>> filter(func,seq)
    6 ['aaa', 'x35']

    还有个叫做lambda表达式的特性,可以创建短小的函数。

    1 >>> filter(lambda x:x.isalnum(),seq)
    2 ['aaa', 'x35']

    貌似都不常用。

     

  • 相关阅读:
    Gitlab CI/CD
    PYTHON第三方库
    linux中shell脚本的新建、编辑和执行
    装饰器案例 python
    VMware无法为 vGPU "profile_name" 初始化插件
    veritas nbu 命令查看许可
    传统媒体该做什么
    文件映射
    前端网页的分页简单实现
    reg ,如何编写reg文件
  • 原文地址:https://www.cnblogs.com/dadada/p/3066335.html
Copyright © 2020-2023  润新知