引子

求1-15的和;
求23-36的和;
求55-68的和;

n = 0
for i in range(1, 16):
    n += i
print(n)

m = 0
for j in range(23, 37):
    m += j
print(m)

o = 0
for k in range(55, 69):
    o += k
print(o)
'''
120
413
861
'''
def sum_Of_sum(i1, i2):
    result = 0
    for i in range(i1, i2 + 1):
        result += i
    return result


print(sum_Of_sum(1, 15))
print(sum_Of_sum(23, 36))
print(sum_Of_sum(55, 68))
'''
120
413
861
'''

程序而言:函数就是对程序逻辑进行结构化或者过程化的一种编程方法。

built-in function 内置函数—>BIF

函数的定义

声明函数的一般形式

def function_name(arg1,arg2,...,argn):
    '''statements'''
    func_statements
    return  Value

说明:

1.函数代码块以 def 关键词开头,后接函数标识符名称和小括号 ()。

2.任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

3.函数的第一行语句可以选择性地使用文档字符串----用于存放函数说明。

def add(x,y):
    '''求和'''
    return x+y
print(add.__doc__)  #用__doc__调出函数说明
'''
求和
'''

4.函数内容以冒号起始,并且缩进。

5.return [表达式] 结束函数,选择性的返回一个值给调用方。不带表达式的return相当于返回 None。

其中参数列表和返回值不是必须的,return后也可以不跟返回值,甚至连 return也没有。

对于return后没有返回值的和没有return语句的函数都会返回None值

函数调用

def创建了一个函数但是没有执行它,可以再程序中通过在函数名后增加括号调用这个函数。括号中可以包含一个或多个对象参数,被传递给要执行的函数。

函数参数

函数参数种类

形参和实参

  • 形参
  • 只有在调用时才分配内存单元。调用结束后,即释放所分配的内存单元,因此形参只在内部有效,函数调用结束返回主调用函数后则不能再使用该形参变量
  • 实参
  • 实参是一个确定的值,能够传递给形参
  • 作为未知参数或者关键字

位置参数(必选参数)

def involution(x):  ##x为位置参数
   return x * x
>>>involution(3)
9

关键字参数

是指函数在调用的时候,带上参数的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序调用函数

不定参数

在python中不定参数主要是指*args和**kwargs两个魔法变量

这两个魔法变量主要是用于函数定义,我们可以将不定数量的参数传递给一个函数

  • *args 用来接收任意非键值对的任意数量的参数列表给函数
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],"ab","cd","ef")
'''
普通位置参数: 1 2
不定参数: (3, 4, 'a', 'b')
<class 'tuple'>
普通位置参数: [1, 2, 3] ab
不定参数: ('cd', 'ef')
<class 'tuple'>
'''

计算输入数据的平均值:

def average(*args):
    sum = 0
    for i in args:
        sum += i
        num = len(args)
    print(sum / num)


average(2, 3, 4, 64, 5)
average(3, 90, 23, 765, 23, 1, 3)
'''
15.6
129.71428571428572
'''
  • **kwargs 用来接收任意不定长度的键值对列表给函数
def un_para_key(x, y, *z, **kwargs):
    print(kwargs)
    print(type(kwargs))


un_para_key(1, 2, 3, 4, 5, "a", "b", a=1, b=2, c=3, d=5)
'''
{'a': 1, 'b': 2, 'c': 3, 'd': 5}
<class 'dict'>
'''

函数属性

函数属性是python中另外一个使用了句点属性标识并拥有名字空间的领域

内嵌函数

—>作用域

bar()整个函数都处于外部foo()函数的作用域里(foo()是我们可以从外部访问的一个对象区域)。除了在foo()内部,其他地方无法对bar()进行调用

变量作用域

作用域的产生

就作用域而言,python和C有很大差别,只有当变量在module,Class,函数中定义的时候,才会有作用域概念;

在作用域中定义变量,一般只在作用域内有效。需要注意的是,在if-else,for-else,while等关键字的语句块中不会产生作用域。

作用域的类型

python中,使用一个变量时并不要求需要预先声明它。但在真正使用的时候,他必须绑定到某个内存对象(被定义,赋值)。这种变量名的绑定将在当前作用域引入新的变量,同时屏蔽外层作用域中的同名变量

局部作用域(locale—L)

局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。

Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。

有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。

局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。
如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。

嵌套作用域(enclosing—E)

  • E也包含在def关键字中,E和L是相对的,E相对于跟上层的函数而言也是L。与L的区别在于,对于一个函数而言,L是定义在此函数内部的局部作用域。
  • 主要为了视线python的闭包,而增加的实现

全局作用域(Global—G)

即使在模块层次中定义的变量。模块顶层声明的变量具有全局作用域。从外部来看,模块的全局变量就是一个模块对象的属性。

内置作用域(built-in—B)

  • 系统固定模块中定义的变量

全局变量和局部变量

gbl1=1
def f():
    global gbl2
    gbl2=2
    loc=3
    return gbl1,gbl2,loc
print(f())
print(gbl1,gbl2)  #2个都是全局变量
print(loc)  #是函数体内定义的局部变量
'''
(1, 2, 3)
1 2
NameError: name 'loc' is not defined
'''

当没有调用过f()函数时,直接访问gbl2也会报错(NameError)

def foo():
    a=666
    print("foo(),修改前:\t",a)
    a=888
    print("foo(),修改后:\t",a)
def bar():
    print("bar(),a:\t",a)
foo()
bar()
'''
foo(),修改前:	 666
foo(),修改后:	 888
bar(),a:	 6688
'''