您的位置:首页 > 编程语言 > Python开发

python的最最最最最基本语法(2)

2016-11-07 10:47 218 查看
函数的定义:

使用
def
语句,依次写出函数名、括号、括号中的参数和冒号
:
,然后,在缩进块中编写函数体,函数的返回值用
return
语句返回。

当用return 返回多个值时,返回的其实是一个tuple,即元组。

当一个语句块是什么也不做时,请用pass语句,如果为空的话,分出错的。

如果函数没有return或者只有单单的一个reuturn时 , 则返回none。

>>> def sum(x, y):
...     sum = x + y
...     return sum
...
>>> print sum(1,2)
3

函数的参数问题:


函数可以有默认的参数:且函数的默认参数必须指向不变的对象(否则有逻辑错误)。

>>> def sum(x=1, y=2):
...     return x + y
...
>>> print sum()
3
>>> print sum(5)
7
>>> print sum(y=10)
11

函数的可变参数:定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个
*
号。在函数内部,参数
numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数。另外,Python允许你在list或tuple前面加一个
*
号,把list或tuple的元素变成可变参数传进去。

#可变参数;
>>> def sum(*numbers):
...     sum = 0
...     for num in numbers:
...             sum = sum + num
...     return sum
...
>>> sum(1,2,3)
6
>>> sum(1,2,3,4,5,6)
21

#把list或tuple元素变为可变参数传入
>>> list = [1,2,3,4,5,6,7,8]
>>> sum(*list)
36
>>> tuple = (1,3,4,75)
>>> sum(*tuple)
83

关键字参数:它也是可变的,仅仅在参数前面加了两个
*
号。这些关键字参数在函数内部自动组装为一个dict,Python允许你dictionary前面加*
*
号,把dictionary元素变成可变参数传进去。。

>>> def person(name, age, **other):
...     print 'name:',name,'\n'\
...           'age:',age,'\n'\
...           'other:',other
...
>>> person('xiaoming',18,sex='boy')
name: xiaoming
age: 18
other: {'sex': 'boy'}

#把dictionar元素参数传入
>>> dic = {'sex':'boy','tall':174}
>>> person('xiaohong',22,**dic)
name: xiaohong
age: 22
other: {'tall': 174, 'sex': 'boy'}

参数可以组合使用:在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。

另外,对于对于任意函数,都可以通过类似
func(*list, **dictionary)
的形式调用它,无论它的参数是如何定义的。

对于递归函数:优点是定义简单,逻辑清晰。但是有一个问题,使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。



高阶函数:就是能接收其它函数作为参数的函数。


#定义一个简单的高阶函数:
>>> def add(x, y, f):
...     return f(x) + f(y)

#定义一个函数:
def square(x):
...     return x * x

#調用高阶函数:
>>> add(5,6,square)
61


map()高阶函数

map()
函数接收两个参数,一个是函数,一个是序列,
map
将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。


#map函数分别用函数对传入的元素做处理哦
>>> def square(x):
...     return x*x
>>> list = range(1,6)
>>> list
[1, 2, 3, 4, 5]
>>> map(square, list)
[1, 4, 9, 16, 25]


reduce()高阶函数

reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4).


#看看reduce,把[1, 2, 3, 4, 5] 变为 一个数:12345
>>> list
[1, 2, 3, 4, 5]
>>> def func(x, y):
...     return x*10 + y
...
>>> reduce(func, list)
12345


filter()高阶函数:

filter()
函数用于过滤序列。接收一个函数和一个序列。
filter()
把传入的函数依次作用于每个元素,然后根据返回值是
True
还是
False
决定保留还是丢弃该元素。

def is_odd(n):
return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
# 结果: [1, 5, 9, 15]

排序算法:sorted()函数

通常规定,对于两个元素
x
y
,如果认为
x < y
,则返回
-1
,如果认为
x == y
,则返回
0
,如果认为
x > y
,则返回
1
,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。

>>> sorted([123,34,654,24,623342,4546,32,0])
[0, 24, 32, 34, 123, 654, 4546, 623342]


另外,它也可以接收一个函数,用于自定义的排序。

#定义一个倒序
>>> def reversed_cmp(x, y):
...     if x > y:
...         return -1
...     if x < y:
...         return 1
...     return 0
...

>>> sorted([123,34,654,24,623342,4546,32,0],reversed_cmp)
[623342, 4546, 654, 123, 34, 32, 24, 0]



返回函数这个变量:可以在一个函数里面在定义一个一个函数,并返回这个函数名。

内部函数可以引用外部函数的参数和局部变量,当内部函数名被返回时,外部函数的相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。


来,举例说明:

>>> def sum(x, y):
...     def sum1():
...             return x + y
...     return sum1

>>> f = sum(1, 2)
>>> f
<function sum1 at 0x7fab499ec8c0> #可以看出 f 为一个函数变量哦;
>>> f()     #返回这个函数的值;
3

看下面两个程序,仔细体会哦:

>>> def func1():
...     i = 1
...     def func2():
...             return i * i
...     return func2
...
>>> f = func1()
>>> f()
1



>>> def func1():
...     i = 1
...     def func2():
...             return i * i
...     i = 5
...     return func2
...
>>> f = func1()
>>> f()
25

看到了吧,返回的函数没有立刻执行,而是直到调用了
f()
才执行。当执行时,i 变为了5。

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

我们可以这样做,让它保证不受影响,这样做的原因是因为已经把函数func2()的参数绑定了哦,为1。

>>> def func1():
...     i = 1
...     def func2(i):
...             def func3():
...                     return i * i
...             return func3
...     return func2(i)
...     i = 5
...
>>> f = func1()
>>> f()
1


匿名函数:有些时候,不需要显式地定义函数,直接传入匿名函数更方便。


关键字lambda表示匿名函数,匿名函数有个限制,就是只能有一个表达式,返回值就是该表达式的结果。

下面见识一下匿名函数哦:

>>> list = range(1,11)
>>> list
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> map(lambda x: x*x ,list)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]


函数装饰器:


就是说,我们想对一个函数进行增强一些功能,但是呢,我们又不修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数。

一些额外的知识:函数对象都有一个__name__的属性,可以得到函数名字。如:

>>> def hello():
...     print 'hello,world'
...
>>> f = hello
>>> hello.__name__
'hello'
>>> f.__name__
'hello'


看看下面实现的decorator:

#定义了一个函数的decorator;
def f1(func):
def f2(x, y):
print 'i am using decorator'
print 'call %s ' %func.__name__
return func(x, y)
return f2

#用 @ 语法,把decorator置于函数的定义处,即邦定函数哦;
@f1
def sum(x,y):
return x + y

#调用它:
print sum(2,3)

输出为:

i am using decorator
call sum
5

这是的@f1,就相当于 sum = f1(sum);

再看一个哈,我们可以给decorator传入一定的参数哦:

# 定义一个函数的decorator;
def f1(name):
def f2(func):
def f3(x, y):
print 'my name is %s' %name
print 'i am using decorator'
print 'call %s ' %func.__name__
return func(x, y)
return f3
return f2

#用 @语法哦;
@f1('yinheyi')
def sum(x,y):
return x + y

#调用它
print sum(2,3)

输出为:

my name is yinheyi
i am using decorator
call sum
5

这是的@f1('yinheyi') 相当于 sum = f1('yinheyi') (sum);

对于上面的操作还有一些小问题:

上面的sum.__func__ 变为了f3,而不再是sum。所以:需要把原始函数sum的
__name__
等属性复制到
f3
函数中,否则,有些依赖函数签名的代码执行就会出错。

Python内置的
functools.wraps
就是干这个事的,所以, 在加入这个一句就可以啦:具体如下:

# 添加这个库
import functools

def f1(name):
def f2(func):
@functools.wraps(func)    #加入这个一个语句哦;
def f3(x, y):
print 'my name is %s' %name
print 'i am using decorator'
print 'call %s ' %func.__name__
return func(x, y)
return f3
return f2

@f1('yinheyi')
def sum(x,y):
return x + y
print sum(2,3)
print 'the name of sum is \'%s\'' %sum.__name__

输出为:

my name is yinheyi
i am using decorator
call sum
5
the name of sum is 'sum'


偏函数:
functools.partial
帮助我们创建一个偏函数。它的作用为:把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。


举例说明,如int()函数,它可以把字符串转换为整数,加外,它还提供了额外的base参数,如果传入
base
参数,就可以做N进制的转换。如:

int('12345', base=8)
5349


当我们想假设要转换大量的二进制字符串,每次都传入
int(x, base=2)
非常麻烦,于是,我们想到,可以定义一个
int2()
的函数,默认把
base=2
传进去:

def int2(x, base=2):
return int(x, base)

functools.partial
就是帮助我们创建一个偏函数的,不需要我们自己定义
int2()
,可以直接使用下面的代码创建一个新的函数
int2


>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

所以,简单总结
functools.partial
的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

注意到上面的新的
int2
函数,仅仅是把
base
参数重新设定默认值为
2
,但也可以在函数调用时传入其他值:

>>> int2('1000000', base=10)
1000000


最后,如果你觉得以上内容对你有帮助,如果你有钱的话,如果你愿意的话,可以打赏一下我这个穷学生哦,以资助我买几本书。靠劳动吃饭,应该不会被你们唾弃吧,





哈哈哈,自愿自愿哈……

您可以选择:2毛,5毛、1元。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: