Python—函数

函数

引子:

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

built-in function 内置函数—>BIF

函数的定义

声明的一般形式:

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

说明如下:

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

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

​ 3.函数的第一行语句可

以选择性地使用文档字符串----用于存放函数说明。

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

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

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

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

有些函数可能既不需要传递参数,也没有返回值。

没有参数时,包含参数的圆括号也必须写上,圆括号后也必须有“:”。

demo:

def sum_of_num(i1,i2):
    """求和"""
    result=0
    for i in range(i1,i2+1):
        result+=i
    return result

print(sum_of_num(1,15))
print(sum_of_num.__doc__)   

120
求和

函数调用

def a(name,age):
    b = {'name': name, 'age': age}
    return b
print(a('city',1999))

函数文档说明

def sum_of_num(i1,i2):
    """求和"""
    result=0
    for i in range(i1,i2+1):
        result+=i
    return result
print(sum_of_num.__doc__)   

求和

函数参数

  • 不传参函数

  • 参数函数

    • 顺序 输入变量名字定义要放后面
    def a(name,age):
        b = {'name': name, 'age': age}
        return b
    print(a(name='city',1999))
    
    SyntaxError: positional argument follows keyword argument
    
    def a(name,age):
        b = {'name': name, 'age': age}
        return b
    print(a('city',age=1999))
    
    {'name': 'city', 'age': 1999}
    

函数返回值

函数参数种类

形参和实参

  • 形参

    • 只有在调用时才分配内存单元。调用结束后,即释放所分配的内存单元。因此,形参只在内部有效,函数调用结束返回主调用函数则不能再使用该形参变量
  • 实参

    • 实参是一个确定的值,能够传递给形参
      • 作为位置参数或者关键字参数传递
def usr_manage(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, '-'))
usr_manage('Tom',20,'IT','Coding')
usr_manage('Jim',20,'Student','Coding')

-----用户管理系统-----
	Name:	 Tom
	Age:	 20
	Job:	 IT
	Hobby:	 Coding
-----用户管理系统-----
-----用户管理系统-----
	Name:	 Jim
	Age:	 20
	Job:	 Student
	Hobby:	 Coding
-----用户管理系统-----

只传递参数,位置一一对应—>位置参数

使用位置参数时和函数头定义的形参在顺序,个数以及类型上匹配

默认值参数、关键字参数

默认参数,关键字参,必须放置于位置参数之后

def usr_manage(name='x',age='x',job='x',hobby='x'):
    print('用户管理系统'.center(16,'-'))
    print('\tName:\t',name)
    print('\tAge:\t', age)
    print('\tJob:\t', job)
    print('\tHobby:\t', hobby)
    print('用户管理系统'.center(16, '-'))
usr_manage('Tom',hobby='Coding',age=20)
usr_manage('Jim',20,'Student',)

-----用户管理系统-----
	Name:	 Tom
	Age:	 20
	Job:	 x
	Hobby:	 Coding
-----用户管理系统-----
-----用户管理系统-----
	Name:	 Jim
	Age:	 20
	Job:	 Student
	Hobby:	 x
-----用户管理系统-----

不定参数

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

他们俩主要用于函数定义,我们可以将不定数量的参数传递给一个函数

  • *args*用来接收任意非键值对的任意数量的参数列表给函数
  • **kwargs用来接收任意不定长度的键值对列表给函数
def uncertain_para(para,*args):
    print('普通位置参数:',para)
    print('不定参数:', args)
    print(type(args))
uncertain_para(1,2,3,4,'a','b')
uncertain_para([1,2,3,4],'a','b','ed')

普通位置参数: 1
不定参数: (2, 3, 4, 'a', 'b')
<class 'tuple'>
普通位置参数: [1, 2, 3, 4]
不定参数: ('a', 'b', 'ed')
<class 'tuple'>               # 一个星号返回元组

def un_para_key(**kwargs):
    print(kwargs)
    print(type(kwargs))
un_para_key(a=1,b=2,c=3)

{'a': 1, 'b': 2, 'c': 3}
<class 'dict'>                # 两个星号返回字典

def un_para_key(x,y,*z,**kwargs):
    print(kwargs)
    print(x,y,z)
    print(type(kwargs))
un_para_key(1,2,3,'a','b','c',a=1,b=2,c=3)

{'a': 1, 'b': 2, 'c': 3}
1 2 (3, 'a', 'b', 'c')
<class 'dict'>

函数引用

def foo():
    print('in foo()')
    bar()
def bar():
    print('in bar()')
foo()

in foo()
in bar()      # 只要定义在引用之前运行,定义中的函数变量不会报错

你可以获得每个 pyhon 模块,类,和函数中任意的名字空间。你可以在模块 foo 和 bar 里都有名为 x 的一个变量,,但是在将这两个模块导入你的程序后,仍然可以使用这两个变量。所以,即使在两个模块中使用了相同的变量名字,这也是安全的,因为句点属性标识对于两个模块意味了不同的命名空间,比如说,在这段代码中没有名字冲突:

函数属性

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

def foo():
    'foo() --- properly created doc string'
def bar():
    pass
bar.__doc__='oops,forget the doc str above'
bar.version=0.1

>>> dir()
['__annotations__', '__builtins__', '__cached__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'bar', 'foo', 'li', 'random', 'string']
>>> bar.__doc__
'oops,forget the doc str above'
>>> bar.version
0.1
>>> foo.__doc__
'foo() --- properly created doc string'
>>>

内嵌函数

—>作用域

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

def foo():
    def bar():
        print('bar() called.')
    print('foo() called.')
    bar()
foo()
bar()

foo() called.
Traceback (most recent call last):
bar() called.
  File "D:/PycharmProjects/1/day.py", line 414, in <module>
    bar()
NameError: name 'bar' is not defined

变量作用域

作用域的产生

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

def foo():
    a='foo'
    print(a)
foo()
print(a)

Traceback (most recent call last):
  File "D:/PycharmProjects/1/day.py", line 420, in <module>
    print(a)
NameError: name 'a' is not defined
foo

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

作用域的类型

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

  • 局部作用域(locale—L)

    • 局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。
      注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。
  • 嵌套作用域(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)
print(loc_str)

Traceback (most recent call last):
  File "D:/PycharmProjects/1/day.py", line 428, in <module>
    print(loc_str)
NameError: name 'loc_str' is not defined     # 不能在外部引用局部变量
foobar
foo

def foo():
    a=666
    print('foo(),修改前a:\t',a)
    a=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

a=6688
def foo():
    # a=666
    print('foo(),修改前a:\t',a)   #在未定义前引用变量 报错
    a=888       #全局变量与局部变量的变量名相同,优先搜索到局部变量
    print('foo(),修改后a:\t', a)
def bar():
    # a=6688
    print('bar(),a:\t',a)
foo()
bar()

  File "D:/PycharmProjects/1/day.py", line 432, in foo
    print('foo(),修改前a:\t',a)
UnboundLocalError: local variable 'a' referenced before assignment
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值