python高级 之(一) --- 函数类型

函数

模块

  模块: 一个py文件就是一个模块, 每个模块之间是可以相互访问的 访问之前需要进行导入

  分类: 1.系统提供的模块 math random

     2.自己自定义的,自己封装的常用功能的的py文件

     3.第三方模块需要进行安装。安装格式: pip install 三方模块名

  导入:1. import 模块名 ;使用:模块名.内容

      import random;random.randint(1, 100)

     2. from 模块 import 具体某个内容

      from random import randint;使用:randint(1, 100)

     3. 通配符*导入 泛指该模块中所有的内容

      from 模块名 import *

 

  包:类比成计算机中的文件夹,一个个的文件夹就是在对计算机中的内容进行分类整理的 方便于查找东西。

    计算机中的文件不允许重名,就想保存两个重名的文件,把他们放在不同的文件夹中

  作用:对模块进行分类管理。给模块提供了多级命名空间。有了包之后,导入该包下面的模块。导入方式: import 一级包名.二级包名....n级包名.模块名

  程序中建包:右键建立包的位置-- new -- python package;建完包之后 包中有一个__init__.py文件。

  作用:向解释器解释类似于计算机中文件夹的是一个项目的包 不是一个普通文件夹。

     普通的文件夹 没有再程序中为模块提供多级命名空间的作用。不同的普通文件夹中 模块不能相互访问

程序入口设定

   程序入口:完成一个程序 需要几个py文件配合才能完成程序的运行。需要给一个标记 让别人知道到底是从哪个 文件开始启动执行的

       在启动执行的文件中加一个if判断。判断__name__的值,如果是起始文件 __name__的值就等于 __main__;如果不是 __name__ 的值他对应的模块名 

   判断格式:if __name__ == "__main__":启动文件的执行内容 

可变参函数

可变参数

  有一种需求,在封装功能的时候并不能确定到底有多少个未知项参与功能运算 也就无法确定声明函数时形参个数。

  把这个参数设置可变参数 ---> 使用一个形参接受多个实参 ---> 这个形参在函数中是容器[元组来存放的]

声明可变参数的格式

  def 函数名(*变量名, 形参1,.., 形参n):

    功能的运算

    return 结果   # 没有结果返回 此句可省

 1 """
 2 求n个数的累加和。将型参封装为可变参数
 3 """
 4 def nums_sum(*num):
 5     print(num)
 6     '''
 7     结果是元组容器:(12, 34, 56, 74, 86)
 8     也可以接收实参是 元组、列表、集合等类型。
 9     但是直接传递一个容器过来,会当作一个元素存在元组中。
10     若想传递成功,需要让实参和型参等价。即实参加*号
11     '''
12     total = 0
13     for ele in num:
14         total += ele
15     return total
16 if __name__ == '__main__':
17     res = nums_sum(12,34,56,74,86)
18     print(res)
19 
20     tuple0 = (77,45,86,34,23,23)
21     res = nums_sum(*tuple0)  # 让实参和型参等价。即实参加*号
22     print(res)

关键字参数

 关键字参数

  调用者调用函数的时候可以传入0个或者多个带有形参名的关键字参数

  声明函数时,有确定的形参个数,传递实参的 需要形参一一对应

  为了避免形参多的情况下传递实参的顺序不太确定,可以传递实参的时候采用:

    函数名(形参名=实参, 形参名=实参) 

  这种是根据形参名找到对应的形参为其赋值,不用担心顺序的问题

   命名关键字参数:

  调用者可以传入 形参名中没有设定 关键字参数 到底传入什么数据 需要在函数中进行判定:

  例如网站注册用户时:

    必填项 ---> 已知形参

    选填项 ---> 可以使用命名关键字参数 接收时的格式:形参名=实参

  声明方式:

    接受调用者传递的位置的关键字数据时 在函数中是通过字典来接受

    def 函数名(形式参数1, 形式参数2, ... ,形式参数3, **参数名): 

       函数功能

 1 def accept(name,password,**kwargs):
 2     print(kwargs) # 结果:{'sex': '女', 'city': '北京'}
 3     if 'city' in kwargs:
 4         print("用户的居住地:",kwargs['city'])
 5     if 'sex' in kwargs:
 6         print("用户的性别:", kwargs['sex'])
 7 if __name__ == '__main__':
 8     accept("yaya","123456",sex="",city='北京',)
 9     
10     dict0 = {'a':97,'b':78} # 也可以穿入字典类型,加**符号
11     accept("pepe",'123456',**dict0)

匿名函数

   匿名函数:生成函数一种简单方式 ---> 简单函数封装的简化。匿名函数执行一次就释放掉

 使用要求:函数功能中只有一个return语句就能结束函数的这种形式可以简化成匿名函数

 声明格式:lambda 形参1,形参2, .., 形参n : 功能的结果[功能的结果只能使用一句代码表示]

 使用场景:对一般型参中接收函数时,可以使用匿名函数来进行传递。这样比传递一个参数是带名函数节省方法池的内存

1 def add(a, b):
2     return a + b
3 """等价于"""
4 lambda a, b : a + b
1 # 对一般型参中接收函数时,可以使用匿名函数来进行传递。这样比传递一个参数是带名函数节省方法池的内存
2 list0 = [-19,33,54,75]
3 max_value = max(list0,key=lambda n:-n)
4 print(max_value)
5 # 要求是根据字典中年龄对列表进行降序排序
6 person_list = [{'name':'Tom','age':23},{'name':'Lili','age':45},{'name':'Susan','age':32}]
7 person_list.sort(key=lambda p_dict:p_dict['age'])
8 print(person_list)

偏函数

 偏函数:偏函数是对原本存在的函数的一种修改。借助偏函数 对使用场景比较多的函数进行修改来满足场景的需求

 两种方式:

  自定义一个方法 间接执行原本设计的方法

  使用系统提供的 funstools模块有一个方法可以转换对方法默认值的使用

 1 # 原来使用
 2 print('a',end='\t')
 3 print('a',end='\t')
 4 
 5 # 自定义可变参数
 6 def cus_print(*value):
 7     print(*value,end='......')
 8 # 再次使用时
 9 cus_print('a','b')
10 cus_print('c','d')
11 
12 # 系统提供的方法
13 import functools
14 func = functools.partial(print, end="!!!!")
15 func('good')

闭包

 闭包:在一个函数中声明另外一个函数 这种格式就叫做闭包

 作用域: 只有函数有独立的作用域 在函数中声明的内容仅在函数中有效 出了函数没有任何意义 例如在函数中声明的局部变量

1 # 闭包
2 def outer():
3     print('外部函数')
4     def inner():
5         print('内部函数')
6     # 只能在外部函数中调用inner
7     inner()
8 outer()

 global

  使用场景:在函数中使用修改成全局变量 需要在函数内部对该变量进行全局标记 否则的话 会将该变量解释为在函数中重新声明的局部变量 与全局变量无关

 nonlocal

  使用场景:闭包中如果想在内层函数中 使用修改外层函数声明的局部变量 需要对该变量进行nonlocal标记 否则会被解释成 在内部函数重新声明一个变量 与外部函数的变量无关

 


装饰器

  参考下一篇笔记 :https://www.cnblogs.com/TMMM/p/11395710.html 

生成器

  生成器 :

  根据逻辑生成一个存放数据的容器。弥补了列表生成式的弊端。

  生成器节省了内存,当生成器产生的时候 数据不会立即存放在内存中,而是取出一个存放一个

  与列表生成式的区别:

  列表生成式可以快速生成一批数据存放在内存中。列表生成式有一个弊端:

  如果生成了大量的数据 但是只使用 前面一些的数据,此时使用列表生成式就非常的浪费内存

  生成器有两种方式生成数据:

  将列表生成式的中括号换成小括号(生成的数据 数据的来源 对数据的进行筛选)

  类似于方法的声明 需要每次调用方法的时候需要返回生成的数据 。不是使用return 返回 [因为return直接结束函数] 使用yield代替return返回生成器中的数据

  生成器中获取数据

  通过next的方法 将数据从生成器中一个一个的取出

  已经取出数据了 再使用next获取数据 获取的是下一个数据 不会重复的获取同一个数据

 1 # 生成器的第一种方式生成和获取数据
 2 ge = (num for num in range(1,1000))
 3 print(ge) # 其类型 结果:<generator object <genexpr> at 0x106b9c480>
 4 value = next(ge)
 5 print(value) # 结果是:1。再次执行next(ge),结果是:2
 6 # 获取前10个数据
 7 for _ in range(10):
 8     value = next(ge)
 9     print(value)
10 '''
11 遍历的时候 需要将对应的值赋予给变量 就得起一个变量的名字来存放数据
12 遍历的时候 只是为了获取循环的次数,为不会获取序列中的元素 就可以使用_占位符变量
13 '''
14 
15 # 生成器的第二种方式生成和获取数据
16 def get_value():
17     for i in range(1,1000):
18         yield i # 此处并非结束函数,如果在yield后面还有平级的语句是会被执行的,但是是在第二次获取的时候执行
19 ge = get_value()
20 print(ge) # 其类型 结果:<generator object <genexpr> at 0x106b9c480>
21 value = next(ge) 
22 print(value)

  注意: 当生成其中的数据取完之后,再去取数据,就回报错

迭代器

  遍历序列:for 变量 in 序列

  迭代器:是相当于另外一种遍历序列的方式,通过next方法一个一个进行迭代 移动取数据的。如果一个序列想使用迭代器 前提这个序列是可以迭代的

  collections模块:Iterator   --- 迭代器

          Iteratable --- 验证序列是否可以迭代

 1 from collections import Iterable,Iterator
 2 
 3 # 验证指定数据是否是可迭代类型的
 4 res = isinstance(10,Iterable)
 5 print(res) # 结果 :False。 整型是不可以迭代的
 6 
 7 res = isinstance('10',Iterable)
 8 print(res) # 结果 :True。字符串类型是可以迭代的
 9 
10 res = isinstance(('10'),Iterable)
11 print(res) # 结果 :True。元组类型是可以迭代的
12 
13 res = isinstance(['10'],Iterable)
14 print(res) # 结果 :True。列表类型是可以迭代的
15 
16 res = isinstance({'10'},Iterable)
17 print(res) # 结果 :True。集合类型是可以迭代的
18 
19 res = isinstance({'10':10},Iterable)
20 print(res) # 结果 :True。字典类型是可以迭代的
21 """
22 Iterable 这个类型验证的结果是:所有的序列都是可以迭代的[遍历],for in 进行遍历
23 能用for in进行遍历的序列,不一定能用迭代器进行遍历。迭代器遍历使用next方法一个一个迭代的
24 生成器 --- 可以使用next来迭代 --- 就可以使用迭代器迭代。
25 列表 --- 可以使用for in进行遍历 --- 但不能使用迭代器迭代
26 """
27 
28 # 若想使用迭代器进行迭代列表类型,需要使用iter(序列)进行转换,
29 # 转化成Iterator迭代器的类型才可以使用next方法进行遍历迭代
30 list0 = [12,34,64,76,34,5,86]
31 it = iter(list0)
32 value = next(it)
33 print(value) # 结果:12
34 value = next(it)
35 print(value) # 结果:34
posted @ 2019-08-28 12:48  Tom's  阅读(325)  评论(0编辑  收藏  举报