定义:
①函数是组织好的,可以重复使用的,用来实现单一,或相关联功能的代码段
②函数能提高应用的模块性,和代码的重复利用率
格式:
①函数代码块使用def
关键字开头,后接函数标识符名称
和圆括号()
②任何传入参数和自变量必须放在括号中间。圆括号之间可以用于定义参数。
③函数的第一行语句可以选择性地试用文档字符串——用于存放文档说明
文档字符串以'''
或者 """
开头和结尾
④函数体以 :
开始,并且需要每段都缩进
⑤return[表达式]
结束函数,选择性的选择一个值给调用方。不带表达式的 return
相当于返回None
函数可以返回多个值,但是其实返回的是一个元组
语法:
def functionname( parameters ): """函数_文档字符串""" function_suite return [expression]
其中:
functionname是函数名称;
parameters是参数名称;
function_suite是函数体;
expression是表达式;
注意:默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配的。
pass语句什么都不做,可以用它作为占位符,当不知道这个函数需要干什么,就可以使用它,让程序跑起来。
①函数调用只需要给一个函数名称,圆括号以及圆括号里的参数,函数调用就是执行函数。
function_name(args)
①在Python中,类型(=后)属于对象,变量(=前)是没有类型的;
a=[1,2,3] b="中国" #以上代码中,[1,2,3]是List类型,"中国"是String类型,而变量a和b没有类型,它仅仅是一个对象的引用(一个指针),可以指向List类型对象,也可以指向String类型对象
②在Python中,定义函数时的参数是形式参数,调用函数时的参数是实际参数;
③在Python中,有不可更改对象(Number,String,Tuple)和可更改对象(List,Dictionary,Set)
不可更改对象:对象一定义就不可更改
可更改对象:对象定义后也可以更改
④在Python中,函数的参数传递:
不可变类型:类似c++的值传递,不影响对象本身。如整数,字符串,元组
可变类型:类似c++的引用传递,影响对象本身。如列表,字典,集合。
⑤**在Python中,一切都是对象,严格说引用我们不能说值传递还是引用传递,我们应该说是传递不可变对象和传递可变对象 **
在Python中,调用函数时可以使用的正式参数类型:必备参数,关键字参数,默认参数,不定长参数
①必备参数需要以正确的顺序传递参数
②调用时参数的数量必须和声明时的一样
#定义一个函数 def printme( str ): '''打印任何传入的字符串''' print(str) return #调用printme函数 printme("我爱祖国!")
①定义函数时可以给参数提供一个默认值
②调用函数时,默认参数的值如果没有传入,则被认为是默认值。
#定义一个函数 def printme( name , str="祖国" ): '''打印任何传入的字符串''' print(f"{name}爱{str}!") return #调用printme函数 printme("张三")
注意:
#默认参数的坑: def add_end(L=[]): L.append('END') return L add_end() #result:['END'] add_end() #result:['END','END'] add_end() #result:['END','END','END'] 原因:Python函数在定义时,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,他指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了 #修改: def add_end(L=None): if L is None: L=[] L.add_end('END') return L
# *args def calc(*numbers): sum=0 for n in numbers: sum=sum+n*n return sum calc(1) calc(1,2,4) calc(1,2,3,4,4) #因为有for循环,所以numbers一定是一个list|tuple,所以传递参数时需要list|tuple作为参数,但由于参数使用的是可变参数,而可变参数本身就是一个tuple来接收参数,所以不需要再传参数时传入list|tuple #如何把num作为可变参数传进去: #方法:在list|tuple前加*变成可变参数,然后再传入进去。 num=[1,2,3] def calc(*numbers): sum=0 for n in numbers: sum=sum+n*n return sum calc(*num)
# **KWargs def person(name,age,**KWargs): print('name:',name,'age:',age,'other:',KWargs) person('xwh',12) #问题:如何把dict作为关键字参数传入进去 #方法:在dict前加**变成关键字参数,然后再传入进去。 ps={'city':'wh'} def person(name,age,**KWargs): print('name:',name,'age:',age,'other:',KWargs) person('xwh',12,ps)
*
隔开,*
后面的参数被视为命名关键字参数# * def person(name,age,*,city,job): print(name,age,city,job) person('xwh',24,city='wh',job='aj')
global
l = [1,2,3,4,5] s = l print(l) print(s) s.append(6) print(l) print(s)
l = [1,2,3,4,5]
:因为当创建列表时,是将对列表的引用赋值给了变量。s = l
:而这行代码只是将l中的列表引用拷贝到s,而不是列表本身。这就意味着存储在l和s中的值,现在都指向了同一个列表。所以只有一个列表。如果s对其列表进行操作,那么也就是l对此列表进行同样的操作,所以l中的值改变了。当函数被调用时,参数的引用被赋值给函数的形式参数,对于列表(字典,集合)等可变类型数据,函数的形式参数得到的是引用的拷贝,所以在函数中修改了参数的值,那么原参数也会被修改。
当函数被调用时,参数的引用被赋值给函数的形式参数,对于数字,字符串,元组等不可变类型数据,由于不可变类型一经创建就不可以修改,所以赋值代表创建了新的对象,所以在函数中修改了参数的值,那么原参数不会被修改。
f1()
中定义另一个函数 f2()
,并且,内部函数 f2()
可以引用外部函数 f1()
的参数和局部变量,当 f1()返回f2()
时,相关的参数和变量都保存在返回的函数中,这就称之为闭包
f1()
时,每次调用都会返回一个新的函数,即使传入的参数相同在Python中使用Lambda来创建匿名函数
①lambda只是一个表达式,函数体比def简单得多
②lambda的主体是一个表达式,而不是代码块。仅仅能在lambda中封装有限的逻辑进去。
③lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
④虽然lambda看起来只能写一行,却不等同于c或c++中的内联函数,后者的目的是调用小函数时不占用内存从而增加运行效率。
⑤语法:
lambda [arg1[,arg2,...,argn]]:expression
#使用lambda sum = lambda s1,s2:s1+s2 #调用sum函数 print(f"s1+s2的值是{sum(1,2)}")
def now(): print('2021-3-11') print("函数也是变量now=",now) f = now print("函数对象可以被赋值给变量f=",f) print("变量也可以调用函数f()=",f())
__name__
属性:获取函数名称print("函数对象的‘__name__’属性获取函数名",now.__name__)
@
语法 ,把装饰器置于函数定义处def log(func): def wrapper(*args,**kw): print("call %s():" % func.__name__) return func(*args,**kw) return wrapper #log()内部定义wrapper(),并且log()返回wrapper() # @log == log(now) @log def now(): print('2021-1-2') now()
functools.partial
的作用就是:把一个函数的某些参数给固定住(即设置默认值),返回一个新的函数