4.Python基础学习笔记day04-函数
一、函数概述
'''
函数:
在项目开发的过程中,有些功能代码我们可能会经常使用,我们可以将这些代码按照它的功能
封装成函数,在需要的时候调用即可。
优点:
1.提高代码的复用性,简化代码结构
2.增加代码的可维护性
'''
'''
函数的定义:
def 函数名(参数列表):
函数体
return 表达式
def 关键字标识定义函数的开始
函数名 遵循标识符的命名规则
() 列表参数的开始以及结束,无论是否存在参数,小括号都不能省略
参数列表 参数与参数之间使用逗号隔开,若不存在参数可不写
: 函数的功能以冒号开始,并且需要缩进
函数体:封装的函数的功能
return 函数结束之后的返回值,若没有返回值return可以不写,不写的时候默认return None.
'''
def myprint():
for x in range(5):
print("you are a good man")
'''
需求:按照传递的num来决定打印的条数
'''
def myprint2(n):
for x in range(n):
print("you are a good man")
myprint2(9)
二、函数参数
'''
形参:形式参数
定义在函数的参数列表中的参数,我们称之为形参。
作用:用来接收函数的调用者传递过来值。
实参:实际参数
函数调用的过程中传递的参数
作用:给形参赋值
参数传递的本质:实参给形参赋值的过程。
对于不可变类型的传递是值传递
对于可变类型的传递是地址传递【引用传递】
若传递进去的对象是不可变类型,当在函数体内对象发生改变的时候,不会改变被传递的变量
若传递进去的变量是可变类型,当在函数内对该变量进行更改的时候,会影响到被传递的变量
'''
str1 = "hello world"
def func1(x):
print(id(x))
x = "abc"
print(x)
print(str1)
print(id(str1))
func1(str1)
print(str1)
list1 = [1,2,3,4]
def func2(x):
print(x)
print(id(x))
x[-1] = "change"
print(x)
print(id(x))
print(list1)
print(id(list1))
func2(list1)
print(list1)
'''
位置参数【又称必选参数】
传递参数的顺序与定义的顺序有关,必须按照定义的顺序来进行传递。
传递参数的个数与参数的个数必须保持一致。
关键字参数:
指函数调用的时候,可以通过"键-值"的形式来加以指定,
可以清除位置关系。
当出现位置参数与关键字参数的时候,需要将位置参数写在关键字参数前面
默认参数
定义函数的时候,我们可以给参数提供默认值,调用函数的时候可以传递此参数
可以不传,当传递此参数的时候,函数则使用传递的参数,若不传递则使用默认值。
优点:方便函数的调用
注意:
1.若默认参数与位置参数同时存在的时候,位置参数要写在默认参数的前面
2.给定默认参数的时候,默认参数需要指向不可变对象。
'''
def ins1(name,age):
print("大家好我是%s,我今年%d岁"%(name,age))
ins1("lili",18)
ins1(age=20, name="zhangsan")
def ins(name,age,address="江西"):
print("大家好我是%s,我今年%d岁,我家乡在%s"%(name,age,address))
ins1("wangwu",18)
'''
不定长参数:
定义函数的时候,我们不确定调用的时候到底会传递多少参数进来【可能传递1个也可能多个或者不传递】
此时我们可以使用不定长参数来解决【不定长参数又包括包裹位置参数与包裹关键字参数】
特点:能处理比声明时候更多的参数【传递多少参数,处理多少参数,不传递不处理】
不定长参数分为两种:
包裹位置参数:
使用:*变量名 一般用*args
功能:可以收集除了必选参数以外剩余的位置参数,按照元组来进行处理
包裹关键字参数:
使用:**变量名 一般用**kwargs
功能:收集除定义的变量的关键字参数之外,剩余关键字参数。
包裹关键字参数只处理剩余的关键字参数,收集作为字典来进行处理。
注意:当位置参数【必选参数】,默认参数,包裹位置参数,包裹关键字参数同时存在
的情况下,一般的顺序为:
位置参数,默认参数,包裹位置参数,包裹关键字参数
默认参数与包裹位置参数可以根据需求,位置可以调换
'''
def mySum(*args):
print(type(args))
sum = 0
for i in args:
sum += i
return sum
print(mySum(1, 2, 3, 4, 5, 6, 7))
def func2(**kwargs):
print(kwargs)
print(type(kwargs))
func2(x=1, y=2, z=3)
def func(*args,**kwargs):
pass
三、匿名函数
'''
匿名函数:
定义:指的是一类无须定义标识符【函数名】的函数或者子程序。
在python中定义匿名函数使用lambda来进行定义。
语法:
lambda 参数列表: 表达式
特点:
1.lambda后面的跟的只是一个表达式,结构体比def的简单
2.参数列表可以有多个参数,参数与参数之间使用逗号隔开
3.无须写return,表达式的结果就是该表达式的返回值。
优点:
1.结构简单
2.匿名函数没有名字无须担心函数名的冲突。
匿名函数的调用:
将lambda表达式赋值给一个变量,通过调用变量来调用我们的匿名函数。
'''
func = lambda a, b: a if a>b else b
print(func)
print(type(func))
print(func(10,20))
四、zip函数
'''
zip函数
zip(iter1,iter2,...)
功能:打包,将可迭代对象中对应位置的元素进行打包,
长度取决于最短的那个,返回zipobj打包好的对象,以迭代器的方式返回
zip(*zipobj)
解包,将之前打包的元素进行解包处理,以迭代器方式返回。
'''
list1 = [1,2,3,4,5]
list2 = ["hello","good","nice","great","hi"]
list3 = ["hello2","good2","nice2","great2"]
zipobj = zip(list1,list2,list3)
print(next(zipobj))
print(list(zipobj))
obj = zip(*zipobj)
print(next(obj))
五、装饰器
'''
装饰器:
在代码运行的期间动态的增加功能的方式我们称之为装饰器。
'''
'''
最简单的装饰器:
def outer(func):
def inner():
#增强的功能
#在内函数中执行func函数
return func()
return inner
在装饰器中,分为外函数与内函数:
外函数(outer):
1.将被装饰的函数传递进来--》func
2.将装饰好的函数返回给调用者 --》inner
内函数:
1.添加动态增加的功能
2.执行被装饰的函数
内函数中return什么时候可以省略?
注意:当被装饰的函数没有返回值的时候,内函数的return可以省略,
若被装饰的函数中存在返回值,则内函数的return则不能省略。
@装饰器
def func():
pass
@的功能:将被装饰的函数的函数名作为参数传递给外函数,将外函数返回的
替代版的函数赋值给原本的函数。
'''
def outer(func):
def inner():
print("*********")
return func()
return inner
@outer
def now():
print("2019-6-13")
return True
print(now())
'''
*********
2019-6-13
True
'''
'''
有参数的情况下
def outer(func):
def inner(参数列表):
#添加增加的功能
return func(参数列表)
return inner
注意:
1.使用内函数来接收被装饰函数的参数
2.调用被装饰的函数的时候,需要将参数传递进去。
'''
def outer(func):
def inner(age):
if age>=0 and age<=160:
func(age)
else:
print("年龄有误")
return inner
'''
使用装饰器,给函数添加一个对年龄的限制:
年龄[0,160]
'''
@outer
def getAge(age):
print("您的年龄为%d"%age)
getAge(-100)
getAge(100)
getAge(200)
六、偏函数
import functools
'''
偏函数:将函数的某些值给固定住,给你返回一个新的函数,这个函数就是偏函数的功能。
newfunc = functool.partial(func,参数)
要导入 functools库
'''
'''
需求:
将二进制的字符串转为十进制
'''
print(int("1010101",base=2))
def int2(str1,base=2):
return int(str1,base)
int3 = functools.partial(int,base=2)
print(int3("1010101"))
print(int3("101001"))
print(int3("101010"))
七、变量作用域与global关键字
'''
变量的作用域:变量起作用的范围。
程序中变量并不是在任意的地方都能访问,访问范围取决于它在赋值的位置【定义的位置】
局部作用域:在函数中定义的变量,每当函数被调用的时候它都会产生一个新的作用域,
这个新的作用域我们称之为局部作用域,在局部作用域中定义的变量,我们称之为局部变量
局部变量起作用的范围就是当前所在的这个函数。
嵌套作用域:又称函数作用域
全局作用域:在模块中定义的变量,并且定义在函数体之外的变量,
他们产生的作用域叫做全局作用域,这个变量我们称之为全局变量。
全局变量作用的范围整个.py文件。
内置作用域:
系统内部定义的变量产生的作用域,叫做内置作用域。
起作用的范围,所有的.py文件。
搜索变量的优先级:
局部作用域>嵌套作用域>全局作用域>内置作用域,
当这几个作用域中都不存在的时候则报错。
'''
'''
注意:在局部作用域中,不能直接更改全局变量的值,若有需要在局部作用域中更改
全局变量,则需要在更改之前对此变量进行声明,使用关键字global进行声明,
声明之后变可更改。
注意:在python中,只有模块,类以及函数【def,lambda】这些才会引入新的作用域,
而其他的语句块比如:if/else,while/for,try/except这些语句块不会引入新的作用域
也就是说在这些语句中定义的变量,在外部仍然可以使用。
'''
num1 = 100
def func():
global num1
num1 = 200
print(num1)
for x in range(10):
pass
print(x)
func()
print(num1)
八、回调函数、返回函数、闭包与递归函数
'''
回调函数:将函数作为参数传递到另外一个函数中,
这个被传递进去,后来又被调用的函数,我们称之为回调函数。
'''
def wake1(time):
print("在%s点,使用揪耳朵的方式叫醒。。。"%time)
def wake2(time):
print("在%s点,使用泼冷水的方式叫醒..."%time)
def wake_server(func,time):
return func(time)
wake_server(wake1,"下午一点五十")
'''
返回函数:把函数作为返回值返回的时候,我们可以称这个函数为返回函数
'''
def lazy_sum(*args):
def calc_sum():
sum1 = 0
for i in args:
sum1 += i
return sum1
return calc_sum
print(lazy_sum(1,2,3,4,5)())
'''
闭包:在外函数的内部定义了一个内函数,内函数使用了外函数的临时变量,
外函数的返回值是内函数的引用【内函数的函数名】,这时候就构成了一个闭包。
一般情况下当函数执行完毕,函数中所有的东西都会被释放掉还给内存,这时候局部变量也会消失,
但是当外函数结束的时候,发现自己还有临时变量在内函数中还会使用,此时外函数会将自己的临时变量
绑定内函数,自己再结束。
函数中的变量在函数被调用的时候创建,在函数执行结束的时候被销毁。
装饰器一定是闭包,但是闭包不一定是装饰器。
'''
def outerfunc():
list1 = []
for x in range(10):
def inner():
return x
list1.append(inner)
return list1
list1 = outerfunc()
for f in list1:
print(f())
'''
函数在内部是可以调用其他函数的,当被调用的函数是函数自己本身的时候,我们称这个函数为递归函数。
使用递归函数的时候,一定要注意栈溢出的情况。
一般情况下不建议使用递归函数。
'''
'''
n! = 1x2x3x...xn
1.写出临界条件:1! = 1
2.找出这次跟上次的关系
3.假设函数可以使用,根据上一次的值,求出本次的结果
f(n) = f(n-1)xn
f(n-1) = f(n-2)x(n-1)
...
f(2) = f(1)*2
f(1) = 1
'''
def f(n):
if n == 1:
return 1
else:
return f(n-1)*n
九、os模块使用
import os
'''
os.getcwd() current working directory
功能:获取当前文件所在目录绝对路径
os.listdir(path)
功能:获取指定目录下所有文件的文件名,若不指定path则获取当前目录下的。
os.path.abspath(path)
功能:获取path的绝对路径【将path与当前文件所在目录的路径进行拼接处理】
os.path.split(path)
功能:将路径分解为目录与文件的部分,以元组的方式返回。
【实际上使用"/"对路径进行切分,从右往左切,切一次,左边获取到的就是目录部分,右边就是文件部分】
os.path.join(path,paths)
功能:对path进行路径拼接,若在paths中出现绝对路径,则前面的路径不保留,返回的后面的绝对路径。
os.path.dirname(path)
功能:返回path中目录的部分。
os.path.basename(path)
功能:返回path中文件的部分
os.path.getsize(path4)
功能:获取指定路径文件的大小,目录的大小获取不到。
os.path.exists(path)
功能:判断指定的路径是否存在,若存在则返回True,否则返回False
os.path.isdir(path)
功能:判断指定的路径是否为目录,若是则返回True,否则返回False
os.path.isfile(path)
功能:判断指定的路径是否为文件,若是则返回True,否则返回False
'''
'''
os.remove(path)
功能:删除指定的文件
os.mkdir(path)
功能:创建指定的目录
os.rmdir(path)
功能:删除指定的空目录【只能删除一层】
os.removedirs(path)
功能:递归删除多层空目录【不存在文件】
os.makedirs(path)
功能:递归创建多层空目录
os.chdir(path)
功能:切换到指定的目录
'''