文章目录
- 函数使用
- 定义一个函数
- 函数的参数和返回值
- 定义参数
- 函数的调用
- 必备参数
- 默认参数
- 不定长参数
- 参数调用
- 关键字参数
- 案例
- 值传递
- 引用传递
- 返回值
- Python内置函数
- Python简单内置函数
- dir
- 常见函数
- Python高级内置函数
- enumerate
- eval
- exec
- map
- filter
- zip
- hasattr(object,name)
- getattr
- setattr(object,name,value)
- 函数文档
- 文档的写法
- 文档查看
- 函数是代码的一种组织形式
- 一个函数一般完成一项特定的功能
函数使用
- 函数需要先定义
- 使用函数,俗称调用
定义一个函数
- 只是定义的话不会执行
- def 函数名()
- 函数名自己定义,起名需要遵循命名规则(约定俗成,大驼峰只给类用)
- 后面括号和冒号不能省,括号内可以有参数
- 参数元组形式可以放到参数最前面,字典形式只能放到最后面
- 函数内所有代码缩进
def func()
print("hello python!")
函数的参数和返回值
- 在Python中参数无类型,参数可以接受任意对象,只有函数中代码才会对参数类型有限制
定义参数
- 负责给函数传递一些必要的数据或者信息
- 参数分类:必备参数,默认参数,不定长参数
函数的调用
- 定义函数时有参数,调用时也要有参数,定义时没有参数,调用时也没有,不定长参数,默认参数除外
- 函数调用时,不定长参数可以不传入,也可以传入任意长度
- 函数名后面跟括号
func()
必备参数
- 定义的时候直接定义变量名,调用的时候直接把变量或者值放入指定位置
def 函数名(参数1,参数2…)
函数体 - 调用
函数名(value1,value2…)
- 调用的时候,具体值参考的是位置,按位置赋值
- 形参(形式参数):在函数定义的时候用到的参数,没有具体值,只是一个占位符号,称为形参(参数1,参数2…)
- 实参(实际参数):在调用的时候输入的值(value1,value2…)实参调用
- 参数person只是一个符号,代表的是调用时候的某个数据
- 调用的时候,会用p代替函数中所有的person
def hello(person):
print("{0},你好".format(person))
p = "girl"
hello(p) #girl,你好
默认参数
- 形参具有默认值
- 调用的时候如果没有对应的形参赋值,则使用默认值
def func_name(p1=v1,p2=v2......)
func_block
#调用1
func_name()
#调用2
value1 = 100
value2 = 200
func_name(value1,value2)
- 示例:
- 报名函数,需要知道学生性别
- 学习Python的学生基本都是男生,所以,报名的时候如果没有特别指定,我们认为是男生
def reg(name,age,gender="male"):
if gender == "male":
print("{0} is {1},he is a good student".format(name,age))
print("{0} is {1},she is a good student".format(name,age))
reg("xiaoming",21)
reg("xiaohong",19,"female") #xiaoming is 21,he is a good student
xiaohong is 19,she is a good student
不定长参数
- 把没有位置,不能和定义时的参数位置相对应的参数,放入一个特定的数据结构中
- 语法:
def func(*args,**kwargs):
func_body #可以按照list使用方式访问args得到传入的参数
#调用
func(p1,p2......)
- 参数名args不是必须这么写,但是推荐用args,约定俗成
- 参数名args前需要星号,表示收集参数
- 收集参数可以和其他函数并存
- 示例:
- 函数模拟一个学生进行自我介绍,但具体内容不清楚
- 把args看做tuple
def stu(*args):
print("hello")
for item in args:
print(item)
stu("xiaoming", 22, "heilongjiang")
stu("xiaohong")
stu() #收集参数可以不带任何实参调用,此时收集参数为空tuple
#hello
xiaoming
22
heilongjiang
hello
xiaohong
hello
- 如果使用关键字参数格式调用,会出问题
- 收集参数之关键字收集参数
- 把关键字参数按字典格式存入收集参数
- 语法:
def func(**kwargs):
func_body
#调用
func(p1=v1,p2=v2......)
- 约定俗成用kwargs
- 调用的时候,把多余的关键字参数放入kwargs
- 访问kwargs需要按照字典格式访问
- 案例1:
def stu(**kwargs):
print("hello")
for k,v in kwargs.items():
print(k,"---",v)
stu(name="xiaoming", age=22, addr="heilongjiang")
stu()
#hello
name---xiaoming
age---22
addr---heilongjiang
hello
- 案例2
def func(*args,**kwargs) :
print(args)
print(kwargs)
func(1,2,3,a=4,b=5,c=6) #元组的参数都在左面,字典的参数都在右面,不能混一起
func(*(1,2,3),**{"a":4,"b":5,"c":6})
#(1, 2, 3)
{'a': 4, 'b': 5, 'c': 6}
(1, 2, 3)
{'a': 4, 'b': 5, 'c': 6}
- *args 返回元组,**kwargs 返回字典
- *表示的是展开
a = [1,2,'xiaoge']
b = (1,2,'haha')
c = {'name':'xiaoge','age':15} #*a取字典的键
print(*a,*b,*c) #1 2 xiaoge 1 2 haha name age
参数调用
- 位置参数
- 关键字参数
关键字参数
- 语法:
def func(p1=v1,p2=v2......)
func_body
- 比较麻烦,但有好处:
- 不容易混淆,一般实参和形参只是按照位置一一对应,容易出错(位置参数)
- 使用关键字参数,可以不考虑参数位置
案例
def stu_key(name,age,addr):
print("{} is {},住在{}".format(name,age,addr))
n = "xiaoming"
a = 16
addr = "china"
stu_key('xiaohong',15','diqiu') #位置参数
#xiaohong is 15,住在diqiu
stu_key(age=a,name=n,addr=addr) #关键字参数
#xiaoming is 16,住在china
值传递
- 参数类型为int,float,bool,str,tuple时,在函数里面改变了ta的值,对函数外面值没影响
def test1(m):
print(m)
m = 'new'
print(m)
a = 1
test1(a)
print(a)
#1
new
1
def test2(n):
print(n)
n += 'new', #‘new', 等同于('new',)
print(n)
b = (1,2,3)
test2(b)
print(b)
#(1, 2, 3)
(1, 2, 3, 'new')
(1, 2, 3)
引用传递
- 参数类型是list,dict,在函数里面就可以修改ta的值
def test2(n):
print(n)
n[0] = 'new'
print(n)
b = [1,2,3]
test2(b)
print(b)
#[1, 2, 3]
['new', 2, 3]
['new', 2, 3]
def test3(p):
print(p)
p['age'] = 'new'
print(p)
c = {'name':'xiaoge','age':15}
test3(c)
print(c)
#{'name': 'xiaoge', 'age': 15}
{'name': 'xiaoge', 'age': 'new'}
{'name': 'xiaoge', 'age': 'new'}
返回值
- 函数和过程的区别:有无返回值
- 函数的执行结果
- 使用return关键字,如果没有return,默认返回一个none
- 函数执行后返回值
- 函数一旦执行return语句,则无条件返回,即结束函数的执行
- 推荐写法:不论有没有返回值,都以return结束
- 案例1:
def hello(person):
print("(0),你好".format(person))
return "end"
p = "girl"
rst = hello(p)
print(rst) #girl,你好
end
- 案例2:
def func1():
print("func1")
a = func1()
print(a)
print("*"*10)
def func2():
print("func2")
return "ok"
b = func2()
print(b) #func1
None
**********
func2
ok
Python内置函数
Python简单内置函数
- 内置对象查看:dir
- 常见函数:len(求长度),min(求最小值),max(求最大值),sorted(排序),reversed(反向),sum)(求和)
- 进制转换函数:bin(转换为二进制),oct(转换为八进制),hex(转换为十六进制),ord(字符转ASCII码),chr(ASCII码转字符)
dir
- dir():查看当前模块的属性列表
- dir([ ])查看列表的方法,也可以查看字典等基本类型
常见函数
- 作用于字符串,列表等
a = ‘sdfgfd’ - len(a) #6
- sorted(a) #[‘d’, ‘d’, ‘f’, ‘f’, ‘g’, ‘s’] #按ascii码表从小到大排序
- sorted()是python的内置函数,并不是可变对象(列表、字典)的特有方法,sorted()函数需要一个参数(参数可以是列表、字典、元组、字符串),无论传递什么参数,都将返回一个以列表为容器的返回值,如果是字典将返回键的列表。
- reversed(a) #<reversed at 0x7f254db0f080>
- list(reversed(a)) #[‘d’, ‘f’, ‘g’, ‘f’, ‘d’, ‘s’]
Python高级内置函数
- enumerate,exec,map,eval,filter,zip
enumerate
- 多用于for循环
- 根据可迭代对象创建枚举对象
seasons = ["spring","summer","fall","winter"]
list(enumerate(seasons))
#[(0,spring),(1,summer),(2,fall),(3,winter)]
list(enumerate(seasons,start=1)) #指定起始值
#[(1,spring),(2,summer),(3,fall),(4,winter)]
eval
- 取出字符串中的内容
- 将字符串str当成有效的表达式来求值并返回结果
- 计算指定表达式的值
x = 10
def func():
y = 20 #局部变量y
a = eval("x+y")
print("a:",a) #x没有就调用全局变量
b = eval("x+y",{"x":1,"y":2}) #定义局部变量,优先调用
print("b:",b)
c = eval("x+y",{"x":1,"y":2},{"y":3,"z":4})
print("c:",c)
d = eval("print(x,y)")
print("d:",d) #对于变量d,因为print()函数不是一个计算表达式,因此没有返回值
func()
#a:30
b:3
c:4
10 20
d:None
exec
- exec执行字符串或complie方法编译过的字符串
-exec可以执行复杂的Python代码,而不像eval函数那样只能计算一个表达式的值,返回值永远为none
x = 10
def func():
y = 20
a = exec("x+y")
print("a:",a)
b = exec("x+y",{"x":1,"y":2})
print("b:",b)
c = exec("x+y",{"x":1,"y":2},{"y":3,"z":4})
print("c:",c)
d = exec("print(x,y)")
print("d:",d)
func()
#a:None
b:None
c:None
10 20 #为exec("print(x,y)")的结果
d:None
示例2:
i = 2
j = 3
exec("ans=i+j")
print("answer is:",ans) #answer is 5
map
- map会接收一个函数f和一个list,并通过把函数f依次作用在list的每个元素上,得到一个新的list并返回,会根据提供的函数对指定序列做映射
def square(x):
return x ** 2
list(map(square,[1,2,3,4,5])) #计算列表各个元素的平方
#[1,4,9,16,25]
list(map(lambda x:x**2,[1,3,5,7])) #使用lambda匿名函数
#[1,9,25,49]
- lambda表达式,通常是在需要一个函数,但是不想去命名一个函数的场合下使用的
add = lambda x,y:x+y - 形式:
lambda 参数:表达式
filter
- filter函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代对象,如果要转换成列表,可以用list来转换
list(filter(lambda x:x%2==0,range(1,10))) #[2, 4, 6, 8]
zip
- zip函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元素组成的对象,好处是节约内存,可以用list转换输出列表
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
list(zip(a,b)) #[(1,4),(2,5),(3,6)] #把返回的对象转换成列表
list(zip(a,c)) #[(1,4),(2,5),(3,6)] #元素个数与最短的一致
#zip(*)正好相反用于解压
案例:
a = [1,2,3]
def stu(*args):
print(args)
for i in args:
print(i)
stu(*a)
#(1, 2, 3)
1
2
3
hasattr(object,name)
- 判断object对象中是否存在name属性或者方法,有则返回True,没有则返回False
- 需要注意的是name参数是string类型,所以不管是要判断属性还是方法,其名称都以字符串形式传参;getattr和setattr也同样;
class Test(object):
name = 'haha'
def __init__(self):
print('初始化')
def test(self,a):
self.m = a
if __name__ == '__main__':
print('你看我不到')
t = Test() #你看我不到
初始化
t.test('b') #如果没有这行代码,最后一句就为False,因为t没有调用test方法,当然没有私有属性m
print(hasattr(Test,'name')) #True
print(hasattr(t,'name')) #True
print(hasattr(Test,'__init__')) #True
print(hasattr(t,'__init__')) #True
print(hasattr(Test,'test')) #True
print(hasattr(t,'test')) #True
print(hasattr(Test,'m')) #False
print(hasattr(t,'m')) #True
getattr
- 获取object对象的属性的值,如果存在则返回属性值
- 如果不存在分为两种情况
- 没有default参数时,会直接报错
- 给定了default参数
- 若对象本身没有name属性,则会返回给定的default值
- 另外还需要注意,如果给定的方法test()是实例函数,则不能写getattr(A, ‘test’)(),因为fun()是实例函数的话,是不能用A类对象来调用的,应该写成getattr(A(), ‘func’)();实例函数和类函数的区别可以简单的理解一下,实例函数定义时,直接def func(self):,这样定义的函数只能是将类实例化后,用类的实例化对象来调用;而类函数定义时,需要用@classmethod来装饰,函数默认的参数一般是cls,类函数可以通过类对象来直接调用,而不需要对类进行实例化;
class Test(object):
name = 'haha'
def __init__(self):
print('初始化')
@classmethod
def cls(cls):
return '我是类函数'
def test(self,a):
self.m = a
if __name__ == '__main__':
print('你看我不到')
t = Test() #你看我不到
初始化
t.test('b')
print(getattr(Test,'name')) #haha
print(getattr(t,'name')) #haha
print(getattr(Test,'__init__')) #<function Test.__init__ at 0x7f060726d510>
print(getattr(t,'__init__')) #<bound method Test.__init__ of <__main__.Test object at 0x7f06071ade80>>
print(getattr(Test,'test')) #<function Test.test at 0x7f06071b2158>
print(getattr(t,'test')) #<bound method Test.test of <__main__.Test object at 0x7f06071ade80>>
print(getattr(t,'m')) #b #如果没有t.test('b')会报错
print(getattr(Test,'m')) #没有default参数,自动报错
AttributeError: type object 'Test' has no attribute 'm'
print(getattr(Test,'m',20)) #20 给default参数
print(getattr(Test(),'test')('c')) #初始化
c
print(getattr(t,'test')('c')) #c
print(getattr(Test,'cls')) #<bound method Test.cls of <class '__main__.Test'>>
print(getattr(Test,'cls')()) #我是类函数
print(getattr(t,'cls')) #<bound method Test.cls of <class '__main__.Test'>>
print(getattr(t,'cls')()) #我是类函数
setattr(object,name,value)
- 给object对象的name属性赋值value
- 如果对象原本存在给定的属性name,则setattr会更改属性的值为给定的value
- 如果对象原本不存在属性name,setattr会在对象中创建属性,并赋值为给定的value
- 一般先判断对象中是否存在某属性,如果存在则返回;如果不存在,则给对象增加属性并赋值
class Test(object):
name = 'haha'
def __init__(self):
print('初始化')
@classmethod
def cls(cls):
return '我是类函数'
def test(self,a):
self.m = a
return self.m
if __name__ == '__main__':
print('你看我不到')
print(getattr(Test,'name')) #你看我不到
haha
setattr(Test,'name','hengheng')
print(getattr(Test,'name')) #hengheng
函数文档
- 函数的文档的作用是对当前函数提供使用相关的参考信息
文档的写法
- 在函数内部开始的第一行使用三引号字符串定义符
- 一般具有特定格式
文档查看
- 使用help函数,形如help(func)
- 使用__doc__
def stu(age,name,*args):
"""
hello
everyone
"""
print("这是文档")
help(stu)
# stu(age, name, *args)
hello
everyone
hello
everyone
print(stu.__doc__)
#hello
world
:param a:
:param b:
:param args:
:return: