Python函数相关

使用函数的目的: 可读性强,复用性强

# 函数签名: 函数签名值得是函数名,参数个数和类型以及返回值类型

定义函数:

def 函数名:
    功能
    return "返回值"

 

return 返回值的几种情况详解

  没有返回值的情况:返回None

    1.不写 return;

    2.只写return;(结束一个函数的继续);

    3.return None;不常用;

  返回一个值:

    1.可以返回任何数据类型;

    2.只要返回就可以接受到;

    3.如果在一个程序中有多个return,那么只执行第一个;

  返回多个值:

    1.多个返回值用多个变量接受:有多少返回值就用多少个变量接受;

    2.多个返回值用一个变量接受:得到的是一个元祖;

 

函数参数的几种情况详解

  没有参数:

    定义函数和调用函数时括号里都不写内容;

  有一个参数:

    传什么就是什么;

  有多个参数:

    1.站在实参的角度上:

      1.按照位置传参;

      2.按照关键字传参;

      3.混着使用(必须先按着位置传参,在按照关键字传参;不能给一个变量传多个值);

    2.站在形参的角度上:

 

      1.位置参数:必须传,且有几个参数传几个值;

      2.默认参数:可以不传,如果不传就是驶入默认的参数,如果传入就使用传入的参数;在形参中 --- '形参'='默认值';


    ***默认参数的陷阱:如果默认参数的值是一个可变数据类型,那么每一次调用函数的时候,如果不传值就公用这个数据类型的资源;默认参数可变数据类型只要不重新赋值,list指向的地址永远不变,切记切记!

    ***顺序:必须先定义位置参数,*args,后再定义默认参数,再写**kwargs;

 

动态参数解释

  可以接受任意个参数

 

  1.*args;# *args(args可以任意变换 习惯使用args) # 接受的是按照位置传参的值,组织成一个元祖;## 站在实参的角度上,给一个元祖加上*,就是将这个元祖按照顺序打散;

  2.**kwargs;# **kwargs(kwargs可以任意变换 习惯使用kwargs) # 接受的是按照关键字传参的值,组织成一个字典;## 站在实参的角度上,给一个字典加上**,就是将这个字典按照顺序打散;

 


 

函数的进阶

命名空间

一个函数具有——python解释器
#1 内置命名空间
  # python解释器一启动就可以使用的名字存储在内置命名空间中;#内置的函数在启动解释器的时候被加载进内存里;
#2 全局命名空间——我们写入的代码而不是函数中的代码
  # 是在程序从上到下被执行的过程中依次加载进内存;#放置了我们设置的而所有变量名和函数名;
#3 局部命名空间——函数
  # 就是函数内部定义的名字;#当调用函数的时候,才会产生这个名字空间,随着函数执行的结束,这个命名空间就消失了;

***依赖倒置关系:内置》》》全局》》》同一个局部(多个局部名字不共享)
在局部:可以使用内置,也可以使用全局的名字;
在全局:可以使用内置,不能使用局部的名字;
在内置:不能使用全局,也不能使用局部的名字;

# 在正常情况下,直接使用内置的名字;
# 当我们在全局定义了和内置名字空间同名的名字时,会使用全局的名字;
# 当使用名字本空间有的情况下,不向上层调用;
# 如果使用名字本空间没有的情况下,找上一层调用,如果内置空间都没有,报错;
# 多个函数应该拥有多个独立的局部名字空间,不互相共享;

 

作用域:

全局作用域:
  # 作用在全局——(内置和全局名字空间中的名字都属于全局作用域);
  # ***globalse();查看全局作用域的名称;
局部作用域:
  # 作用在局部——函数(局部名字空间中的名字属于局部作用域);
  # 对于不可变数据类型 在局部可是查看全局作用域中的变量;不能直接修改,如果需要修改,需要在程序的一开始添加global声明;
  # ***locals();根据locals的位置输出此域的名称;当前可用的变量;

***global;#如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效;

***nonlocal;#只能用于局部变量,找上层中离当前函数最近一层的局部变量;声明了nonlacal的内部函数的变量修改会影响到离当前函数最近的一层的局部变量;

 

函数的本质:函数名就是内存地址
  1.函数名可以赋值;
  2.函数名可以作为容器类型的容器;
  3.函数名可以作为函数的参数;函数名可以作为函数的返回值;
  符合以上三个条件:第一类对象

 

闭包:
  嵌套函数,内部函数调用外部函数的变量
# 闭包的意义
  保证变量不被侵害
  让闭包索使用的变量常驻内存
# 可以通过函数name.__closure__ 只要元祖不为空,则函数为闭包函数

 

三元运算:
  变量=条件返回True的结果 if 条件 else 条件返回Falsh的结果;

 

 


 

装饰器

装饰器的形成过程:
  最简单的装饰器>>>有返回值>>>有一个参数>>>万能参数;

 

装饰器的作用:
  # 不想修改函数的调用方式,但还想再原来的函数前后添加功能

 

装饰器原则:开放封闭原则
  # 开放:对扩展是开放的
  # 封闭:对修改是封闭的

 

语法糖

  1.# @装饰器函数名; #优先执行@后的内容 执行完成后与前面的@拼接为装饰器
  2.# 紧贴着被装饰的函数;

 

装饰器的固定模式:

def wrapper(f): #(warpper 函数名可变 更换过后需要跟后面语法糖@装饰器名称一样#f是被装饰函数)
    def inner(*args,**kwargs):
    #'被装饰之前要做的事'
    ret = f(*args,**kwargs) #装饰器 ret接受inner的返回值 就是被装饰函数的返回值
    #'被装饰之后要做的事'
    return ret
return inner

 

# @wrapper #语法糖 @装饰器函数名
# 被装饰的函数 定义函数时

函数名._name_ ;#查看字符串格式的函数名
函数名._doc_ ;#查看这个函数的注释 doc-document

 

补充:

from functools import wraps (别人已经写好的装饰器)*************
@wraps(inner)********
# 装饰器传参相当于三层闭包 在最外层接受装饰器传入的参数
定义自己装饰器时使用 ---inner前使用 在闭包wrapper中嵌套的inner函数之前使用
不会丢掉原有的名字 和备注信息

 

 


 

迭代器

迭代器的意义
  # 让不同的数据类型拥有相同的遍历方式


迭代器的好处
  # 从容器类型中一个一个的取值,会把所有的值都取到,且一个值只能取一次。
  # 迭代器可以节省空间(未释放前)

 

可迭代协议
  可迭代对象,例如容器,需要有一个__iter__方法,该方法返回一个迭代器对象;

  

迭代器协议
  内部含有和__iter__和__next__方法的就是迭代器;

  可迭代的.__iter__()方法就可以得到一个迭代器;

  迭代器中的__next__()方法可以一个一个的获取值;

 

for循环
  # 只有是可迭代对象的时候才能使用for;
  # 当我们遇到一个新的变量,不确定能不能使用for循环的时候,判断它是否可迭代;

 


***补充:
  可迭代对象 以及生成器都可以转化为迭代器 iter(xxx) 转化完后可以使用__next__()方法

 

***补充:

from itertools import chain
chain() # 将可迭代数据连接起来 
例如:
    a = [1, 2, 3, 4]
    b = ['x', 'y', 'z']
    for x in chain(a, b):
        print(x)
# 输出
1
2
3
4
x
y
z

 


 

 

生成器

***生成器函数:
  只要含有 yield 关键字的函数都是生成器函数;#yield 与 return不可共用,且需要写在函数内部;
  yield返回的是一个生成器;

 

从生成器中取值的几个方法:
  # __next__()
  # for循环
  # 数据类型的强制转换(将生成器里的值全部取出来放到内存中,占用内存)

 

send()

  # send() 获取下一个值得效果和next基本一致;#只是在获取下一个值得时候,给上一个yield的位置传递一个数据;
使用send()的注意事项:
  # 第一次使用生成器的时候 时使用__next__()获取下一个值;
  # 最后一个yield不能接收外部的值;

 

****yield from 

  # 用在生成器里,从一个容器类型里面取得值直接返回 接收到的是分开一个一个的值:例如; 

 

def ceshi():
    a='abcdef'
    yield from a 

g=ceshi()
for i in g:
    print(i) # 结果为 a / b / c /d /e /f  (/为回车)

 


 

列表推导式:(各种推导式)

  list=[i for i in range(10)]#把i放到列表中;(放入的 i 可以操作)
  list=[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型 ];(遍历)

 

完整的列表推导式:
  list=[满足条件的元素相关操作 for 元素 in 可迭代数据类型 if 元素的相关条件];# 满足相关条件执行元素操作;(筛选)

 

生成器表达式:
  g=(每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型)
  g=(i for i in range(10))#g是一个生成器;
  for i in g;print(i) ;将生成器里的值取出来

 


解包

如果列表中有3个元素,那么刚好可以分配给3个变量。除了列表对象可以解包之外,任何可迭代对象都支持解包,可迭代对象包括元组、字典、集合、字符串等;

 


内置函数

python中的内建函数

  callable();#可以检查一个对象是否是可调用的;

  dir();dir() 是一个内置函数,用于列出对象的所有属性及方法。在 Python 中,一切皆对象,模块也不例外,所以模块也可以使用 dir();

  help();# 用于查看函数或模块用途的详细说明;比dir()更加详细,可以查看到内置的注释之类;

  import;#用于动态加载类和函数;#  import  函数名 + 别名;# 重命名 

  open();#文件的操作;

  id();#(内容,打印出内存地址); 

  hash();# 哈希;用于获取取一个对象(字符串或者数值等)的哈希值; 

  input();#函数接受一个标准输入数据,返回为 string 类型。

  print(); # print() 方法用于打印输出,最常见的一个函数;关键字参数(sep -- 用来间隔多个对象,默认值是一个空格。 end -- 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。file -- 要写入的文件对象,flush--输入布尔值,True立即把内容输出到流文件,不作缓存)

  eval();# eval() 函数用来执行一个字符串表达式,并返回表达式的值;# 简单计算类;

  exec();# exec() 将字符串类型的代码执行,没有返回值;# 流程类;

  single();#交互语句使用single 

  compile();compile() 函数将一个字符串编译为字节代码,代码对象能够通过exec语句来执行或者eval()进行求值;参数 source--对象  filename--如果不是从文件读传入'' model--指定编码种类例如evec,eval,single

  ***complex;复数 bytes();

  bytes 函数返回一个新的 bytes 对象,该对象是一个 0 <= x < 256 区间内的整数不可变序列。它是 bytearray 的不可变版本。(***网络编程 只能传二进制 照片和视频,Html网页爬取到的也是bytes编码:

    str>>>bytes***
      str.encode();# encode编码 str.encode('设置编码方式utf-8;utf-16;gbk...')
    bytes>>>str***
      bytes.decode()#decode编码 bytes.decode('设置编码方式utf-8;utf-16;gbk...') )
      参数:source--对象
      如果 source 为整数,则返回一个长度为 source 的初始化数组;
      如果 source 为字符串,则按照指定的 encoding 将字符串转换为字节序列;
      如果 source 为可迭代类型,则元素必须为[0 ,255] 中的整数;
      如果 source 为与 buffer 接口一致的对象,则此对象也可以被用于初始化 bytearray。
      如果没有输入任何参数,默认就是初始化数组为0个元素。

 

 

  bytearray();# bytearray() 方法返回一个新字节数组。这个数组里的元素是可变的,并且每个元素的值范围: 0 <= x < 256。(优点:修改的时候节省内存 缺点:只能通过字符编码修改)

  memoryview();# memoryview() 函数返回给定参数的内存查看对象(Momory view)。所谓内存查看对象,是指对支持缓冲区协议的数据进行包装,在不需要复制对象基础上Python代码访问。

  ord();# ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常   *****(字符转化为Unicode编码  );

  chr();# chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符;(从Unicode编码转化回字符);

  ascll();# 只要是ascll码中的内容,就打印出来;不是的话转化为\u

  repr();# repr() 函数将对象转化为供解释器读取的形式;(repr()保留原格式---%r内部调用的就是repr());(%r打印时能够重现它所代表的对象(rper() unambiguously recreate the object it represents));

  forzenset();#frozenset() 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素;

 

重要的

  len();# len() 方法返回对象(字符、列表、元组等)长度或项目个数;

  enumerate();#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中;

  all();all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False;元素除了是 0、空、FALSE 外都算 TRUE;

  ang();any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。元素除了是 0、空、FALSE 外都算 TRUE;

 

very重要

  zip();zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个迭代器并返还迭代器。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同; 

  sorted();sorted() 函数对所有可迭代的对象进行排序操作。(可以传入key)
  sort 与 sorted 区别:
    1.sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
    2.list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

  filter();filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到迭代器中。(可以传入key)

  map();map() 会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回一个迭代器。(可以传入key);

 

filter() 与 map()   

filter():
  1.执行了filter 之后的结果集合 小于等于执行之前的个数;
  2.filter只管筛选,不会改变原来的值;

map():
  1.执行前后元素个数不变;
  2.值可能发生改变;

 

匿名函数  

  ************函数名=lambda 参数 : 返回值
  可以与 min max filter map sorted 组合使用

  例如

  

my_list = [3,5,-4,-1,0,-2,-6]
sorted(my_list, key=lambda x: abs(x)) # 在遍历my_list 将其元素传入lambda中进行处理

 

补充:

python 基础模块 operator
  # sorted排序非lambda配合包
  # perator模块中另两个非常重要的方法是itemgetter和attrgetter。
  这两个函数可以从一个序列或者对象中去获取指定的元素或属性值。

  例如:attrgetter

class Ob():
    def __init__(name,age,birthday):
        self.name = name
        self.age = age
        self.birthday = birthday    

ob1 = Ob("xx1",20,datetime.date(1992,12,2))
ob2 = Ob("xx2",16,datetime.date(2000,10,20))
ob3 = Ob("xx3",25,datetime.date(1883,3,5))
objs = [ob1,ob2,ob3]                

sorted(objs,key=operator.attrgetter("age"))    # 获取age属性进行排序
sorted(objs,key=operator.attrgetter("birthday.year")) # 获取birthday中的datetime下的year方法进行排序 # 内部通过反射获取对象属性

# itemgetter就是遍历字典等元素使用

 

进制转换

  bin();二进制
  oct();八进制
  hex();十六进制

 

数学类

  abs();# 绝对值;

  divmod();# div 除法 mod 取余 ;除余法;

  round();# round() 方法返回浮点数x的四舍五入值;

  pow();# pow(x, y[, z]),函数是计算x的y次方;如果z在存在,则再对结果进行取模,其结果等效于pow(x,y) %z

  max();求最大值 有个参数key 可以改变方法使用 例如key=abs 以绝对值的方法求最大值;

  min();求最小值 有个参数key 可以改变方法使用 例如key=abs 以绝对值的方法求最小值;

  reversed();reversed 函数返回一个反转的迭代器;

  slice();slice() 函数实现切片对象,主要用在切片操作函数里的参数传递;

 

***format函数:

 

数字          格式       输出       描述
3.1415926        {:.2f}         3.14       保留小数点后两位
3.1415926        {:+.2f}       +3.14       带符号保留小数点后两位
-1           {:+.2f}       -1.00       带符号保留小数点后两位
2.71828         {:.0f}       3         不带小数
5            {:0>2d}      05         数字补零 (填充左边, 宽度为2)
5            {:x<4d}      5xxx        数字补x (填充右边, 宽度为4)
10           {:x<4d}        10xx        数字补x (填充右边, 宽度为4)
1000000        {:,}        1,000,000     以逗号分隔的数字格式
0.25          {:.2%}       25.00%      百分比格式
1000000000       {:.2e}        1.00e+09      指数记法
13           {:10d}        13        右对齐 (默认, 宽度为10)
13           {:<10d}      13        左对齐 (宽度为10)
13           {:^10d}      13        中间对齐 (宽度为10)


11
'{:b}'.2(11)        1011
'{:d}'.format(11)      11
'{:o}'.format(11)      13 进制
'{:x}'.format(11)       b
'{:#x}'.format(11)     0xb
'{:#X}'.format(11)     0xB

 

^, <, > 分别是居中、左对齐、右对齐,后面带宽度, : 号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。

+ 表示在正数前显示 +,负数前显示 -; (空格)表示在正数前加空格

b、d、o、x 分别是二进制、十进制、八进制、十六进制。

此外我们可以使用大括号 {} 来转义大括号

 

 


 

递归函数

递归函数:在函数中调用自身的函数;


RecursionError: maximum recursion depth exceeded while calling a Python object————递归的错误,超过了递归的最大深度
改变递归最大深度:
  import sys
  sys.setrecursionlimit(深度)

 

 

posted @ 2019-10-31 21:14  Binb  阅读(211)  评论(0编辑  收藏  举报