Python中的函数

简介

1、函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
2、函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
3、定义函数使用关键字 def,后跟函数名与括号内的形参列表,参数可为0-多个,参数与参数之间使用逗号隔开。
4、任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
5、函数内容以冒号起始,并且缩进
6、return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

语法

def functionname( parameters ):
   '所有的条件语句'
   return [expression]

实例

# 需求:实现等腰直角三角形
def
triangle(rows):# 这里设定该函数需要有1个参数,所以当函数调用时,也需要传入1个参数,否则报错 print('----------------等腰直角三角形:----------------'+' ') for i in range(0, rows): for k in range(0, rows - i): print(" * ",end='') #end=''可以起到不换行的作用 k += 1 i += 1 print(" ") triangle(6)# 函数调用:函数需要调用,不调用不会被执行
# 需求:校验输入的数据是不是小数
# 思路:
# 1.54  正小数:只有一个小数点;小数点左右都是整数
# -1.23 负小数:只有一个小数点;小数点右边是整数,小数点左边只有一个负号;负号后面是一个整数
# 写法:
def is_float(s):# 校验输入的数据是不是小数,is_float是函数名,s是形参(形式参数)
    s = str(s)
    if s.count('.')==1:
        left,right = s.split('.') # 通过.分割 1.74 ['1','74']
        if left.isdigit() and right.isdigit():
            return True

        elif left.count('-')==1 and left.startswith('-') and left[1:].isdigit() and right.isdigit():
        # left.count('-')代表-负号的数量,left.startswith('-')代表以-负号开头,left[1:].isdigit()代表从下标为1的位置开始取值,right.isdigit()代表右侧是不是正数
            return True
        else:
            return False
    else:
        return False
    pass # pass是占位,啥也不干,如果不写的话,函数会报错。


# is_float(0) # 这里传入的是实参(实际参数)

 参数类型

 位置参数

1、位置参数为必填参数
2、调用函数时根据函数定义的参数位置来传递参数
3、参数顺序和个数必须一一对应
def stu(name,age,grade,score,sex):
    print('age:%s , name:%s , sex:%s , score:%s , grade:%s'%(age,name,sex,score,grade)) # 只是打乱了输出的顺序,但参数的赋值不会改变

stu('xixi',16,100,'高一一班','') # 规定的参数顺序与传参的顺序一一匹配
# stu('111',11) # 个数不匹配,会报错
# stu() # 位置参数为必传参数,不传会报错

 默认值参数

1、默认值参数,用于定义函数,为参数提供默认值
2、调用函数时可传可不传该默认参数的值,不传则使用默认的,传了则使用传了的
3、默认值参数必须出现在所有的位置参数之后,包括函数定义和调用

def stu(name,age,score,sex,grade='高一一班'):
    print('age:%s , name:%s , sex:%s , score:%s , grade:%s'%(age,name,sex,score,grade))

stu('xixi',sex='',score=99,age=16) # 默认值参数为非必传参数,不传grade则使用默认的
stu('xixi',sex='',score=99,age=16,grade='高一二班') # 默认值参数grade传了之后使用传的
# stu('xxx') # 个数不匹配,会报错
# stu() # 位置参数为必传参数,不传会报错

 可变参数,*args

可变参数,用*args表示,当传入的参数不确定时,使用可变参数
*args的特点:
1、它不是必传参数
2、不限制参数的个数
3、传入多个参数的时候他把参数放到一个元组里面
4、*是可变参数,而args只是一个变量,可以叫其他的,只是习惯写args
def send_email(name,age,*args):
    print('hello')
    print('name:',name,'age:',age,'*agrs:',*args)

send_email('溪洋',18) # 位置参数必传,可变参数不必传
send_email('溪洋',18,'可变参数的值1','可变参数的值2') # 传多个时,前边顺序匹配位置参数,剩余的给*args
send_email(1,a='1',b='2') # 会报错,因为可变参数直接传参即可,不接收kv格式

 关键字参数,**kargs

关键字参数,用**kwargs表示,当传入的
**kwargs特点:
1、不是必传参数
2、不限制参数的个数
3、传入多个参数的时候把参数放到一个字典里面
4、必须得使用关键字调用,k=v,k1=v1
5、关键字参数必须跟在位置参数之后
def send_email(name,**kwargs):
    print('hello')

send_email(1) # 位置参数必传,关键字参数不必传
send_email('小沈阳',别名='小沈阳',英文名='xiaoshenyang') # 位置参数+关键字参数。关键字参数不限制个数;必须跟在位置参数之后
send_email('小沈阳','小沈阳') # 会报错,因为关键字参数调用时必须使用kv形式

 解包参数*与**

1、解包参数*,支持元组、列表、集合、字符串,也支持字典
2、解包参数**,支持字典
#实例演示--定义一个函数
def connect(ip,prot,username,password):
    print(ip)
    print(prot)
    print(username)
    print(password)
1、 -------------------------------   
#定义一个元组
info=('192.168.1.75','3306','www','123456')
#将值取出的普通方式
connect(info[0],info[1],info[2],info[3])
#将值取出的便捷方式
connect(*info)#星号,解包

2、-------------------------------
#定义一个列表
li=['192.168.1.75','3306','www','123456']
#将值取出的普通方式
connect(li[0],[1],[2],[3])
#将值取出的便捷方式
connect(*li)

3、-------------------------------
#定义一个集合
set={'192.168.1.75','3306','www','123456'}
#将值取出的便捷方式
connect(*set)

4、-------------------------------
#定义一个字符串
st='1234'
#将值取出的便捷方式
connect(*st)

5、-------------------------------
#定义一个字典
dic={'ip':'127.0.0.1','prot':'80','username':'root','password':'123456'}
#该方式只会输出key,不会输出values
connect(*dic)
#该方式即可输出values
connect(*dic.values())
#用两个星号,该方式同*dic.values(),记住两个星号只可用于字典
connect(**dic)

全局变量和局部变量

1、函数里边定义的都是局部变量
2、大家都可以用的变量,是全局变量,通常都在代码的最上边定义
3、局部变量调用完就不会占用内存了,而全局变量,会一直占着内存
4、全局变量没有局部变量安全,因为他可以被别人修改,所以全局变量能不用则不用
5、用的时候先从自己的作用域中找,如果找到了就是用自己的,如果没找到,在向上找,找到全局变量

# 不可变的数据类型,如果需要在函数中修改,必须要加global。如:str、int、元组
# 以下为定义的不可变全局变量 language = 'python' num=1 info=(1,2,3) # 可变的数据类型,如果需要在函数中修改,不需要加global。如:字典、集合、列表
# 以下为定义的可变全局变量 list=[1,2,3] dic={'age':'18'} set={123}
# 演示示例
def QA(): print(language) def RD(): global language # 修改全局变量 language。--在修改全局变量时,如果是不可变的数据类型,修改时必须加global language='java' # 将全局变量python修改为了局部变量java print(language) # 输出的language为修改后的:java list.append('hello') # 向list的全局变脸中增加一个值。在修改全局变量时,如果是可变的数据类型,修改时不需要加global def PM(): print(language) # 所以后面在引用的时候就变成了别人修改后的java了 print(list) # 调用list,输出[1, 2, 3, 'hello'],可见在RD函数中增加的值,也影响了全局变量的值 QA() # 使用了全局变量python RD() # 使用了局部变量java,同时修改了全局变量 PM() # 使用全局变量,但是被RD修改成了java,所以用的java print(language) # 打印全局变量,可见已经被RD修改了

 内置函数

内置函数就是Python给你提供的, 拿来直接用的函数,比如print,input,int,list等。

截止到python版本3.6.2 ,一共提供了68个内置函数,具体如下
abs()           dict()        help()         min()         setattr()
all()           dir()         hex()          next()        slice() 
any()           divmod()      id()           object()      sorted() 
ascii()         enumerate()   input()        oct()         staticmethod() 
bin()           eval()        int()          open()        str() 
bool()          exec()        isinstance()   ord()         sum() 
bytearray()     filter()       issubclass()   pow()         super() 
bytes()         float()        iter()         print()       tuple() 
callable()      format()      len()          property()    type() 
chr()           frozenset()   list()         range()       vars() 
classmethod()   getattr()     locals()       repr()        zip() 
compile()       globals()     map()          reversed()    __import__() 
complex()       hasattr()     max()          round() 
delattr()       hash()        memoryview()   set()


以上68个函数,可分综合整理为12类,详情参照:https://zhuanlan.zhihu.com/p/259377922

dir()函数

# dir()函数能够打印出来预使用的模块都有什么方法,在忘记了预使用模块中的方法时使用,用random举例:
import random
age = random.randint(0,99)
name = 'xixi'

print(age) print(dir(random)) # 输出random模块可调用的方法 print(dir(age)) # 输出age变量可调用的方法,因为age是int类型,所以同print(dir(int)) print(dir(name)) # 输出name变量可调用的方法,因为age是str类型,所以同print(dir(str)) # 输出字典的可调用方法的两种写法 print('dict: ',dir({})) print('dict: ',dir(dict)) # 输入列表的可调用方法的两种写法 print('list: ',dir([])) print('list: ',dir(list)) # 输入元组的可调用方法的两种写法 print('tuple: ',dir(())) print('tuple: ',dir(tuple)) # 输入字符串的可调用方法的两种写法 print('str: ',dir('')) print('str: ',dir(str))

# 输出其他内置函数的可调用方法同理,这里不一一赘述

 其他内置函数的常用方法

print(all([1,2,3,4]))#判断可迭代对象中的值是否都为真(非0非空即为真),全为真返回True,有一个为假就返回false
print(any([0,1,2,3,4]))#判断可迭代对象中的值是否有一个为真,有一个为真就返回True,全为假返回false
print(bin(10))#十进制转换为二进制
print(bool('aaa'))#把一个对象转换为bool类型,非0非空即真
print(chr(44))#打印数字对应的ASCII
print(ord('b'))#打印字符串对应ASCII
print(eval('[1,2,3]'))#执行python代码,只能执行简单的,比如可执行简单的运算,定义函数不支持
print(exec('def a():return 5+9'))#执行python代码,一般在线编程就是用的该方式

 匿名函数lambda

函数的特点

1、匿名函数不用取名称,因为给函数取名是比较头疼的一件事,特别是函数比较多的时候
2、可以直接在使用的地方定义,如果需要修改,直接找到修改即可,方便以后代码的维护工作
3、语法结构简单,不用使用def 函数名(参数名):这种方式定义,直接使用lambda 参数:返回值 定义即可
4、lambda用来表示匿名函数,可以传入多个参数,但只能有一个表达式
# 例:以下两种写法同理
def sum(num1,num2):
    return num1*num2
print(sum(2,3)) # >>6

sum2 = lambda num1,num2:num1*num2 print(sum2(2,3)) # >>6

map(),filter()函数

1、map()和filter()这两个函数都是帮你循环调用函数用的,其中:
2、map()会把函数每一次调用的返回值保存,最后返回,True或False
3、filter()帮你过滤你传入的参数,函数的结果返回是true那就保存,返回false就不要。见下方示例
# 例子,列表类型
def add(name):
    return 'cnz_%s'%name
result2 = list(map(add,stus))
result3 = list(filter(add,stus))
print(result2) # >>>['cnz_xixi', 'cnz_yangyang', 'cnz_haha', 'cnz_hehe']
print(result3) # >>>['xixi', 'yangyang', 'haha', 'hehe']

# 例子,int类型
stu_score=[30,60,45,67,86,88,90,100]
def panduan(score):
    return score>=60
result = list(filter(panduan,stu_score))
result1 = list(map(panduan,stu_score))
print(result) # >>>[60, 67, 86, 88, 90, 100]
print(result1) # >>>[False, True, False, True, True, True, True, True]
import random,string,os
stus = ['xixi','yangyang','haha','hehe']

for stu in stus: # 循环stus列表
    os.mkdir(stu) # 将循环出来的值当作名称来创建文件夹
    list(map(os.mkdir,stu.split())) # 使用map方法循环。使用该方法必须将数据类型转换为list,否则无法创建

特殊参数(位置或关键字参数、仅位置参数、仅关键字参数)

任意实参列表

学而时习之不亦说乎!
原文地址:https://www.cnblogs.com/wxinyu/p/14789497.html