python基础05day--函数

一 函数知识体系

什么是函数?
为什么要用函数?
函数的分类:内置函数与自定义函数
如何自定义函数
语法
定义有参数函数,及有参函数的应用场景
定义无参数函数,及无参函数的应用场景
定义空函数,及空函数的应用场景
调用函数
如何调用函数
函数的返回值
函数参数的应用:形参和实参,位置参数,关键字参数,默认参数,*args,**kwargs
高阶函数(函数对象)
函数嵌套
作用域与名称空间
装饰器
迭代器与生成器及协程函数
三元运算,列表解析、生成器表达式
函数的递归调用
内置函数
面向过程编程与函数式编程

二 函数基础

一 引子

 1 1 什么是函数
 2     函数1就是具备某一功能的工具
 3 
 4 
 5 2 为什么要用函数
 6     1  程序的组织结构不清晰,可读性差
 7     2  代码冗余
 8     3  可扩展性差
 9 
10 3 如何用函数
11     函数的使用必须遵循的原则:先定义,后调用
12         修理工事先准备工具的过程即函数的定义
13         修理工遇到应用场景拿来工具就用即函数的调用
14 
15     语法:
16         def 函数名(参数1,参数2,...):
17             """
18             文档注释
19             """
20             code1
21             code2
22             code3
23             ......
24             return 返回值
25 
26         def:定义函数的关键字
27         函数名: 就相当于一个变量名,指向函数的内存地址,
28                 注意:函数的内存地址()就可以出发函数体代码的执行
29 
30         参数: 参数是函数的调用者为函数体代码传值的媒介,在python中函数的参数无需声明类型
31         """文档注释""" : 推荐写上
32         代码块:就是函数体功能的具体实现
33         return 返回值 :函数体代码块运行的成果
34 
35 
36     函数的使用分为两个阶段:
37         定义阶段: 只检测语法,不执行代码
38         调用阶段:运行函数体代码
39             def foo():
40                 xxx
41                 print()

 

二 定义函数

 

三 调用函数

函数的调用:函数名加括号
1 先找到名字
2 根据名字调用代码
无return->None
return 1个值->返回1个值
return 逗号分隔多个值->元组

四 函数的参数

#形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
#1、位置参数:按照从左到右的顺序定义的参数
        位置形参:必选参数
        位置实参:按照位置给形参传值
总结:依位传值
#2、关键字参数:按照key=value的形式定义的实参
        无需按照位置为形参传值
        注意的问题:
                1. 关键字实参必须在位置实参右面
                2. 对同一个形参不能重复传值
总结:依关键词传值
#3、默认参数:形参在定义时就已经为其赋值
        可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
        注意的问题:
                1. 只在定义时赋值一次
                2. 默认参数的定义应该在位置形参右面
                3. 默认参数通常应该定义成不可变类型
总结:选择传值
#4、可变长参数:
        可变长指的是实参值的个数不固定
        而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs

总结:*元组与位置参数转换,**字典与关键字参数转换
#5、命名关键字参数:
    *后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递可以保证,传入的参数中一定包含某些关键字
总结:限制关键词传值

五 练习题

三 函数对象、函数嵌套、名称空间与作用域、装饰器

一 函数对象

#1 可以被引用
#2 可以当作参数传递
#3 返回值可以是函数
#3 可以当作容器类型的元素
 利用该特性,优雅的取代多分支的if
 1 def foo():
 2     print('foo')
 3 
 4 def bar():
 5     print('bar')
 6 
 7 dic={
 8     'foo':foo,
 9     'bar':bar,
10 }
11 while True:
12     choice=input('>>: ').strip()
13     if choice in dic:
14         dic[choice]()

 

二 函数嵌套

三 名称空间与作用域

#名称空间:存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
python test.py
#1、python解释器先启动,因而首先加载的是:内置名称空间
#2、执行test.py文件,然后以文件为基础,加载全局名称空间
#3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
名字的查找顺序
局部名称空间--->全局名称空间--->内置名称空间

 

 1 #1、作用域即范围
 2         - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
 3       - 局部范围(局部名称空间属于该范围):临时存活,局部有效
 4 #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
 5 x=1
 6 def f1():
 7     def f2():
 8         print(x)
 9     return f2
10 x=100
11 def f3(func):
12     x=2
13     func()
14 x=10000
15 f3(f1())
16 
17 #3、查看作用域:globals(),locals()
18 
19 
20 LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
21 locals 是函数内的名字空间,包括局部变量和形参
22 enclosing 外部嵌套函数的名字空间(闭包中常见)
23 globals 全局变量,函数定义所在模块的名字空间
24 builtins 内置模块的名字空间
 1 #global:在局部声明一个名字是来自于全局作用域的,可以用来在局部修改全局的不可变类型
 2 # x=1
 3 # def foo():
 4 #     global x
 5 #     x=2
 6 #
 7 # foo()
 8 # print(x)
 9 
10 #nonlocal:声明一个名字是来自于当前层外一层作用域的,可以用来在局部修改外层函数的不可变类型
11 x=0
12 def f1():
13     x=111
14     def f2():
15         # global x
16         nonlocal x
17         x=222
18     f2()
19     print(x)
20 
21 f1()
22 # print(x)

 

四 闭包函数

闭包的意义与应用

 1 #闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
 2 #应用领域:延迟计算(原来我们是传参,现在我们是包起来)
 3     from urllib.request import urlopen
 4 
 5     def index(url):
 6         def get():
 7             return urlopen(url).read()
 8         return get
 9 
10     baidu=index('http://www.baidu.com')
11     print(baidu().decode('utf-8'))

 

 1 # 为函数体传值的方式一:参数
 2 # def func(x,y):
 3 #     print(x+y)
 4 #
 5 # func(1,2)
 6 
 7 # 为函数体传值的方式二:闭包
 8 # def outter(x,y):
 9 #     # x=1
10 #     # y=2
11 #     def func():
12 #         print(x+y)
13 #     return func
14 #
15 # f=outter(1,2)
16 # f()
17 # f()
18 # f()

 

五 装饰器

装饰器的依据是闭包函数,通过复数闭包实现在不改变原函数的情况下插入操作的目的,即装饰。

1 无参装饰器:
2 def outter(func):
3     def wrapper(*args,**kwargs):
4         前部操作
5         res=func(*args,**kwargs)
6         后部操作
7         return  res
8     return wrapper        
# 有参装饰器的模板
def outter1(x,y,z):
    def outter2(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            return res
        return wrapper
    return outter2
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
wraps补充:
functools.wraps 的作用是将原函数对象的指定属性复制给包装函数对象, 默认有 module、name、doc,或者通过参数选择。
 1 from functools import wraps
 2 
 3 def deco(func):
 4     @wraps(func) #加在最内层函数正上方
 5     def wrapper(*args,**kwargs):
 6         return func(*args,**kwargs)
 7     return wrapper
 8 
 9 @deco
10 def index():
11     '''哈哈哈哈'''
12     print('from index')
13 
14 print(index.__doc__)

 

六 练习题

四 迭代器、生成器、面向过程编程

#1、为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

#2、什么是可迭代对象?
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下
'hello'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__

#3、什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象

 即:iter() 函数用来生成迭代器。

  next() 返回迭代器的下一个项目。

 1 dic={'a':1,'b':2,'c':3}
 2 iter_dic=dic.__iter__()
 3 while 1:
 4     try:
 5         k=next(iter_dic)
 6         print(dic[k])
 7     except StopIteration:
 8         break
 9 等于
10 #基于for循环,我们可以完全不再依赖索引去取值了
11 dic={'a':1,'b':2,'c':3}
12 for k in dic:
13     print(dic[k])
14 
15 #for循环的工作原理
16 #1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
17 #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
18 #3: 重复过程2,直到捕捉到异常StopIteration,结束循环
View Code

生成器:yield

 1 def func():
 2     print('====>first')
 3     yield
 4     print('====>second')
 5     yield
 6     print('====>third')
 7     yield
 8     print('====>end')
 9 
10 f=func()
11 #f=f.__iter__()
12 print(next(f))
13 print(next(f))
14 
15 C:\Users\王康杰\AppData\Local\Programs\Python\Python36-32\python.exe C:/Users/王康杰/PycharmProjects/python博客/8-2.py
16 ====>first
17 None
18 ====>second
19 None
20 
21 进程完成,退出码 0
View Code
 1 def func():
 2     print('====>first')
 3     yield 1
 4     print('====>second')
 5     yield 2
 6     print('====>third')
 7     yield 3
 8     print('====>end')
 9 
10 f=func()
11 #f=f.__iter__()
12 print(next(f))
13 print(next(f))
14 
15 C:\Users\王康杰\AppData\Local\Programs\Python\Python36-32\python.exe C:/Users/王康杰/PycharmProjects/python博客/8-2.py
16 ====>first
17 1
18 ====>second
19 2
20 
21 进程完成,退出码 0
View Code

 

 

五 三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

三元表达式

1 name=input('姓名>>: ')
2 res='SB' if name == 'alex' else 'NB'
3 print(res)

列表推导式

1 #2、语法
2 [expression for item1 in iterable1 if condition1
3 for item2 in iterable2 if condition2
4 ...
5 for itemN in iterableN if conditionN
6 ]

生成器表达式

 1 #1、把列表推导式的[]换成()就是生成器表达式
 2 
 3 #2、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性
 4 >>> chicken=('鸡蛋%s' %i for i in range(5))
 5 >>> chicken
 6 <generator object <genexpr> at 0x10143f200>
 7 >>> next(chicken)
 8 '鸡蛋0'
 9 >>> list(chicken) #因chicken可迭代,因而可以转成列表
10 ['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4',]
11 
12 #3、优点:省内存,一次只产生一个值在内存中

递归

1、递归调用应该包含两个明确的阶段:回溯,递推
    回溯就是从外向里一层一层递归调用下去,
        回溯阶段必须要有一个明确地结束条件,每进入下一次递归时,问题的规模都应该有所减少(否则,单纯地重复调用自身是毫无意义的)

    递推就是从里向外一层一层结束递归
2、

  

1 #总结递归的使用:
2 1. 必须有一个明确的结束条件
3 
4 2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
5 
6 3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

匿名函数

 lambda

内置函数

abs()求绝对值函数

all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。

any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。
# print(any([0,'',None,False]))

# bin 10——》2
# oct 10——》8
# hex 10——》16

bool() 函数用于将给定参数转换为布尔类型,如果没有参数,返回 False。

bool 是 int 的子类。

# res='你'.encode('utf-8')
# res='你'.encode('utf-8')
# res=bytes('你',encoding='utf-8')
# print(res,type(res))

# print(callable(len))

# print(chr(65))
# print(chr(90))
#
# print(chr(97))
# print(chr(122))
#

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

# import time
# print(dir(time))


python divmod() 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
# print(divmod(3003,20))

# for i in enumerate(['a','b','c']):
# print(i)

# res=eval('[1,2,3]')
# print(res,type(res))

# s=set({1,2,3})
# s.add(4)
# print(s)

# fs=frozenset({1,2,3})   frozenset() 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。

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

注意:pow() 通过内置的方法直接调用,内置方法会把参数作为整型,而 math 模块则会把参数转换为 float。

 

# print(pow(2,3,3)) #(2**3)%3

 

# l=[1,'a','3',3]
# l1=reversed(l)函数返回一个反转的迭代器。
# print(list(l1))

# print(round(3.5))round(数值,保留小数位数) 方法返回浮点数x的四舍五入值。

print(round(5656.3657,-2))
5700


l=['a','b','c','d','e']
s='helloworld'

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

class slice(stop) class slice(start, stop[, step])
  • start -- 起始位置
  • stop -- 结束位置
  • step -- 间距


obj=slice(1,5,2)

# print(l[1:5:2])
# print(l[obj])

# print(s[1:5:2])
# print(s[obj])


# print(vars() is locals())vars() 函数返回对象object的属性和属性值的字典对象。

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存

# l=[1,2,3,4,5,6,7]
# s='hello'
#
# res=zip(l,s)
# print(list(res))

__import__() 函数用于动态加载类和函数 。

如果一个模块经常变化就可以使用 __import__() 来动态载入。


# import 'time'
m=__import__('time')
print(m.time())

 


# 面向对象
object.__dict__

classmethod
staticmethod
property

delattr
hasattr
getattr getattr() 函数用于返回一个对象属性值。
setattr setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在

isinstance
issubclass

object

super

eval() 函数用来执行一个字符串表达式,并返回表达式的值。

 1 >>>x = 7
 2 >>> eval( '3 * x' )
 3 21
 4 >>> eval('pow(2,2)')
 5 4
 6 >>> eval('2 + 2')
 7 4
 8 >>> n=81
 9 >>> eval("n + 4")
10 85

exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码。

 1 >>>exec 'print "Hello World"'
 2 Hello World
 3 # 单行语句字符串
 4 >>> exec "print 'runoob.com'"
 5 runoob.com
 6  
 7 #  多行语句字符串
 8 >>> exec """for i in range(5):
 9 ...   print "iter time: %d" % i
10 ... """
11 iter time: 0
12 iter time: 1
13 iter time: 2
14 iter time: 3
15 iter time: 4
 1 x = 10
 2 expr = """
 3 z = 30
 4 sum = x + y + z
 5 print(sum)
 6 """
 7 def func():
 8     y = 20
 9     exec(expr)
10     exec(expr, {'x': 1, 'y': 2})
11     exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
12     
13 func()

 

 

六 函数草稿 

转载于:https://www.cnblogs.com/benjieming/p/9392297.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值