函数
引子
#求1-15的和
sum=0
for i in range(1,16):
sum+=i
print(sum)
#求23-36的和
sum1=0
for i in range(23,37):
sum1+=i
print(sum1)
#求55-68的和
sum2=0
for i in range(55,69):
sum2+=i
print(sum2)
程序而言:函数就是对程序逻辑进行结构化或者过程化的一种编程方法。
built-in function 内置函数---->BIF
def sum(i1,i2):
result=0
for i in range(i1,i2+1):
result+=i
return result
print(sum(1,15))
print(sum(23,36))
print(sum(55,68))
#输出结果:
120
413
861
定义
-
函数代码块以 def 关键词开头,后接函数标识符名称和小括号 ()。
-
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
-
函数的第一行语句可以选择性地使用文档字符串----用于存放函数说明。
-
函数内容以冒号起始,并且缩进。
-
return [表达式] 结束函数,选择性的返回一个值给调用方。不带表达式的return相当于返回 None。
其中参数列表和返回值不是必须的,return后也可以不跟返回值,甚至连 return也没有。
对于return后没有返回值的和没有return语句的函数都会返回None值
有些函数可能既不需要传递参数,也没有返回值。
没有参数时,包含参数的圆括号也必须写上,圆括号后也必须有“:”。
def function(arg1,arg2,...,argn):
'''statements'''
func_statements
return Value
#demo:
def add(x,y):
'''求和'''
return x+y
print(add(4,5))
#输出结果:
9
----------------------------------------
def dict(name,age):
dict = {'name': name, 'age': age}
return dict
print(dict("cl",28))
#输出结果:
{'name': 'cl', 'age': 28}
函数调用
#函数文档说明
函数参数
- 不传参函数
- 参数函数
- 顺序
#函数返回值
函数参数种类
形参和实参
-
形参
- 只有在调用时分配内存单元。调用结束后,即释放所分配的内存单元。因此,形参只在内部有效,函数调用结束返回主调用函数后则不能再使用该形参变量
-
实参
- 实参是一个确定的值,能够传递给形参(作为位置参数或关键字参数传递)。
def user(name,age,job,hobby):
print("用户管理系统".center(16,'-'))
print("\tName:\t",name)
print("\tAge:\t", age)
print("\tJob:\t", job)
print("\tHobby:\t", hobby)
print("用户管理系统".center(16, '-'))
print(user("Tom",20,"IT","Coding"))
#输出结果:
-----用户管理系统-----
Name: Tom
Age: 20
Job: IT
Hobby: Coding
-----用户管理系统-----
只传递实参,位置一 一对应------>位置参数。
使用位置参数时和函数定义的形参在顺序、个数以及类型上匹配。
关键字参数
def user(name,age,job='IT',hobby='Trip'):
print("用户管理系统".center(16,'-'))
print("\tName:\t",name)
print("\tAge:\t", age)
print("\tJob:\t", job)
print("\tHobby:\t", hobby)
print("用户管理系统".center(16, '-'))
print(user("Jack",hobby="Coding",job="student",21))
#报错:
SyntaxError: positional argument follows keyword argument
默认值参数,关键字参数,必须放在位置参数之后。
不定参数
在Python中不定定数主要是指*args和**kwargs两个魔法变量。
他们俩主要是用于函数定义,我们可以将不定数量的参数传递给一个函数。
def uncertain_para(para,para2,*args):
print("普通位置参数:",para,para2)
print("不定参数:",args)
print(type(args))
uncertain_para(1,2,3,4,'a','b')
uncertain_para([1,2,3],4,'a','b')
#输出结果:
普通位置参数: 1 2
不定参数: (3, 4, 'a', 'b')
<class 'tuple'>
普通位置参数: [1, 2, 3] 4
不定参数: ('a', 'b')
<class 'tuple'>
##demo:
def average(*a):
sum=0
for i in a:
sum+=i
return sum/len(a)
print(average(1,2,3))
print(average(2,5,8))
#输出结果:
2.0
6.8
- *args是用来接收任意非键值对的任意数量的参数列表给函数;
- **kwargs用来接收任意不定长度的键值对列表给函数。
##(一个星号返回元组,两个星号返回字典)##
def un_para_key(a,b,*c,**kwargs):
print(a,b,c,kwargs)
print(type(c))
print(type(kwargs))
un_para_key(1,2,3,'a','b',c=6,d=7,e=8)
#输出结果:
1 2 (3, 'a', 'b') {'c': 6, 'd': 7, 'e': 8}
<class 'tuple'>
<class 'dict'>
例题:
#写一个函数,计算传入字符中的数字,字母,空格以及其他字符的个数
def fun(s):
digits = 0
space= 0
alpha = 0
others = 0
for i in s:
if i.isdigit():
digits += 1
elif i.isspace():
space+= 1
elif i.isalpha():
alpha += 1
else:
others += 1
return (digits,space,alpha,others)
r=fun("123_a bs gs1,")
print(r)
#输出结果:
(4, 2, 5, 2)
函数引用
函数属性
函数属性是python中另外一个使用了句点属性标识并拥有名字空间的领域。
>>> def foo():
... 'foo()---Properly created doc string.'
...
>>> def bar():
... pass
...
>>> bar.__doc__='Ooops,forget the doc str above'
>>> bar.version=0.1
内嵌函数
作用域
bar()整个函数都处于外部foo()函数的作用域里(foo()是我们可以从外部访问的一个对象区域)。除了在foo()内部,其他地方无法对bar()进行调用。
>>> def foo():
... def bar():
... print("bar() called.")
... print("foo() called.")
... bar()
...
>>> foo()
foo() called.
bar() called.
变量作用域
作用域的产生
就作用域而言,Python和C有很大差别,只有当变量在module,Class,函数中定义的时候,才会有作用域的概念。
def foo():
a = "foo"
print(a)
print(foo())
print(a)
在作用域中定义的变量,一般只在作用域内有效。需要注意的是,在if-elif-else,for-else,while-else,try-except(else-finally)等关键词的语句块中不会产生作用域。
作用域的类型
Python中,使用一个变量时并不要求需要预先声明它。但在真正使用的时候,他必须绑定到某个内存对象(被定义,赋值)。这种变量名的绑定将在当前作用域引入新的变量,同时,屏蔽外层作用域中的同名变量。
- 局部作用域(locale—L)
- 嵌套作用域(enclosing—E)
- E包含在def关键词中,E和L是相对的,E相对于跟上层的函数而言也是L。与L的区别在于,对于一个函数而言,L是定义在此函数内部的局部作用域。
- 主要为了实现Python的闭包,而增加的实现
- 全局作用域(Global—G)
即在模块层次中定义的变量。模块顶层申明的变量具有全局作用域。从外部来看,模块的全局变量就是一个模块对象的属性。
- 内置作用域(built-in—B)
- 系统固定模块中定义的变量。
搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域。
全局变量和局部变量
局部变量:定义在函数内部的变量称为局部变量,他的作用域范围为函数内,也就是出了函数外就无效。
全局变量:定义在函数外的变量称之为全局变量,他的作用域范围为全局。
gbl_str="foo"
def foo():
loc_str="bar"
return gbl_str+loc_str
print(foo())
print(gbl_str)
#输出结果:
foobar
foo
a=6688 #全局变量
def foo():
a=666 #
print("foo(),修改前a:\t",a)
b=888
print("foo(),修改前a:\t", a)
def bar():
a=6688
print("bar(),a:\t", a)
foo()
bar()
#输出结果:
foo(),修改前a: 666
foo(),修改前a: 888
bar(),a: 6688
当在函数内定义一个与全局变量一样名字的变量时,相当于在函数内重新定义了一个局部变量。因为在函数内重新定义这个变量后,无论在函数内怎样改动这个函数的值,只有在函数内生效,对全局来说是没有任何影响。