Python基础篇-函数

2016-12-14 · 🙈Ray · 0条 · 342次

>_ 创建函数

1.函数是可以调用的,它执行某种行为并且返回一个值。

内建函数callable()可以用来判断函数是否可以调用。

>>> import math 
>>> x = 1 
>>> y = math.sqrt 
>>> callable(x) False 
>>> callable(y) True 
>>> y(4) 2.0 

2.函数使用def定义:

>>> def hello(name): return 'hello, '+ name 
>>> print(hello('Ray')) hello, Ray 

>_ 文档化函数

1.为了让自己和别人更好的理解自己所写的函数,可以加入注释(以#开头)。

另外一种方法是加入字符串,放在def语句的后面,以及模块和类的开头,这种字符串会成为函数或者模块和类的一部分,成为文档字符串。

>>> def square(x): 'calaulates the square of the number x' return x*x 
>>> print(square(2)) 4 

文档字符串可以按照如下方式访问:(__doc__是函数属性)

>>> square.__doc__ 'calaulates the square of the number x'

2.内建的help()函数可以查看函数的帮助信息,包括文档字符串。

>>> help(square) Help on function square in module __main__: square(x) calaulates the square of the number x 

>_ 不返回值的函数

有一些函数可能没有return语句,或者return语句后面什么都没有。但是所有的函数都返回了东西,当不需要它们返回值的时候,它们就会返回None。

>>> def test(): return 
>>> x = test() 
>>> x 
>>> print(x) None 

>_ 参数

1.在函数内为参数赋予新值不会改变外部任何变量的值。

>>> z = 1 
>>> def change1(x): x = 2 
>>> change1(z) 
>>> z 1 
>>> x = ['1','2'] 
>>> y = x[:] 
>>> def change(x): x[0] = 3 
>>> change(x) 
>>> x [3, '2'] 
>>> y ['1', '2'] 
>>> change(y[:]) #这里创建了一个副本,而不是直接把列表放进去。值,而不是引用。 >>> y ['1', '2'] 

2.之前看到的参数都是位置参数,当我们使用函数的时候,必须按声明的顺序写入参数。但有时候参数的顺序不好记,可以提供参数的名字,就不可以打乱参数的顺序了。

>>> def hello(greeting, name): print(greeting+', '+name) 
>>> hello('hello', 'Ray') hello, Ray 
>>> hello('Ray', 'hello') Ray, hello 
>>> hello(name='Ray', greeting = 'hello') hello, Ray 

这类使用参数名提供的参数叫做关键字参数,它的主要作用就是可以明确每个参数的作用。

可以提供默认参数值,同PHP一样,提供默认参数值后,如果没有提供该参数,就会使用默认值。

>>> def hello(greeting = 'hello', name = 'world'): print(greeting+', '+name) 
>>> hello(name = 'Ray') hello, Ray 

3.位置参数和关键字参数和一起使用,但是位置参数必须放置关键字参数的左边。而且只有当强制要求的参数个数比可修改的具有默认值的参数个数少的时候,才这么做。

>>> def hello(name, greeting = 'hello', punctuation = '!'): print('%s, %s%s' % (greeting, name, punctuation)) 
>>> hello('Ray') hello, Ray! 
>>> hello('Ray', punctuation = '.') hello, Ray. 

>_ 收集参数

1.*星号可以将多余的参数收集起来,放置在一个元组中。

>>> def coll1(*x): print(x) 
>>> coll1(1,2,3) (1, 2, 3) 

2.**两个星号可以将关键字参数收集起来,放置在一个字典中。

>>> def coll2(**x): print(x) 
>>> coll2(x='1', y='2') {'x': '1', 'y': '2'} 

3.参数收集的逆过程:

使用*运算符,把元组当作参数使用,使用**运算符将字典当作参数使用。

>>> def add(x,y): return x+y 
>>> param = (1,2) 
>>> add(*param) 3 
>>> param = {'greeting':'hello', 'name':'Ray'} 
>>> def hello(greeting, name): print(greeting + ', ' + name) 
>>> hello(**param) hello, Ray 
>>> def with_stars(**params):
 print(params['name']+ ' is ' +params['age']+'years old!')
>>> def without_stars(params):
 print(params['name']+ ' is ' +params['age']+'years old!')
>>> x = {'name':'Ray', 'age': '22'}
>>> with_stars(**x)
Ray is 22years old!
>>> without_stars(x)
Ray is 22years old!
>>> with_stars(x)
Traceback (most recent call last):
 File "<pyshell#90>", line 1, in <module>
 with_stars(x)
TypeError: with_stars() takes 0 positional arguments but 1 was given
>>> without_stars(**x)
Traceback (most recent call last):
 File "<pyshell#91>", line 1, in <module>
 without_stars(**x)
TypeError: without_stars() got an unexpected keyword argument 'name'
>>> with_stars(name='Ray', age='22')
Ray is 22years old!

*星号只在定义函数(允许使用不定数目的参数)或者调用(“分割”字典或者序列)时才有用。

>_ 作用域

1.变量和所对应的值用的是个“不可见”的字典,内建的vars函数可以返回这个字典。

>>> x = 1 
>>> scope = vars() 
>>> scope['x'] 1 

一般来说,vars所返回的字典是不能修改的,因为根据官方Python文档的说法,结果是未定义的。换句话说,可能得不到想要的结果。

这类“不可见字典”叫做命名空间或者作用域。

2.函数内的变量被称为局部变量。

3.在函数内使用全局变量可能引发很多错误,应该慎重使用。

>>> a = 1 
>>> def add(x): return x+a 
>>> add(3) 4 

4.如果存在与全局变量同名的局部变量,那么就不能在函数内直接使用全局变量,因为它会被局部变量覆盖。但是可以使用globals函数来获取全局变量的值。vars()是获得全局变量的字典,locals()返回局部变量的字典。

>>> a = 1 
>>> def add1(x): a = 2 return a+x+globals()['a'] 
>>> add1(3) 6 

5.如果在函数内部将值赋予一个变量,它会自动变为局部变量——除非告知Python将其声明为全局变量。

>>> x = 2 
>>> def change(): x=3 
>>> change() 
>>> x 2 
>>> def change_global(): global x x = 3 
>>> change_global() >>> x 3 

6.嵌套作用域

Python函数是可以嵌套的,一个函数可以放在另一个函数内。外层函数返回里层函数,内层函数本身被返回了,却没有被调用,而且返回的函数还可以访问它的定义所在的作用域(外层函数的域)。

>>> def outfunc(x): def infunc(y): return x/y return infunc 
>>> a = outfunc(4) 
>>> a(2) 2.0 
>>> outfunc(4)(2) 2.0 

类似infunc函数存储子封闭作用域的行为叫做闭包(closure)。

外部作用域的变量一般来说是不能进行重新绑定的,但是在Python3.0中,nonlocal关键字被引入,它和global关键字的使用方式类似,可以让用户对外部作用域(但并非全局作用域)的变量进行赋值。

>>> def make_counter():
 count = 0
 def counter():
nonlocal count
count += 1
return count
 return counter
>>> make_counter()
<function make_counter.<locals>.counter at 0x03519F60>
>>> a = make_counter()
>>> a
<function make_counter.<locals>.counter at 0x03519FA8>
>>> make_counter()()
1
>>> make_counter()()
1
>>> def make_counter():
 count = 0
 def counter():
count += 1
return count
 return counter
>>> make_counter()()
Traceback (most recent call last):
 File "<pyshell#64>", line 1, in <module>
 make_counter()()
 File "<pyshell#63>", line 4, in counter
 count += 1
UnboundLocalError: local variable 'count' referenced before assignment
>>> a
<function make_counter.<locals>.counter at 0x03519FA8>
>>> a()
1
>>> a()
2
>>> a()
3

>_ 递归

1.递归:函数调用自身。

有用的递归函数包括以下部分:

*当函数直接返回值时有基本实例(最小可能性问题)。当函数不调用本身的时候有返回值。

*递归实例,包括一个或者多个问题较小部分的递归调用。

递归不能永远进行下去。

2.在大多数情况下可以使用循环来代替递归,而且大多数情况下更有效率,但是,递归更加易读,可以大大提高可读性。


  0