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

python基础-函数

2017-08-02 16:19 218 查看

函数

函数的作用是将一坨代码组合到一起实现一个功能,并且可以复用,以简化代码,节省人力。

def functionName(param):
process


函数的定义格式如上

def greet():
print('welcome to pytho
4000
n')
greet()


函数的调用采用的方式是函数名称+(),函数名存放的是对函数对象的引用,所以我们也可以赋值给其它变量.

如:

def greet():
print('welcome to python')
g = greet
g()


上述代码将greet赋值给g,g()也会打印相同的结果

def greet():
print('welcome to python')
def hello():
print('hwllo,python')
def world():
print('world,python')

list = [greet,hello,world]
for x in list:
x();
输出:
welcome to python
hwllo,python
world,python


很显然,我们可以将函数名称组成一个列表,然后遍历调用

def sum(x,y,z=1):
return x+y+z
num = sum(1,2)
print(num)

输出:4


上述我们把z的值默认等于了1,因此sum()函数只需传两个参数即可。

def sum(x=1,y,z):
return x+y+z
num = sum(1,2)
print(num)

输出:    def sum(x=1,y,z):
^
SyntaxError: non-default argument follows default argument


python不允许不带默认参数的参数跟随一个带有默认参数的参数的后面。可以想象,如果sum(1,2)的话,1的值是给x还是给y呢?

def frange(arg0,arg1=None,arg2=None):
'''类似于range()的浮点数生成器'''
start = 0.0
inc = 1.0
if arg2 is not None: #3个参数均有
start = arg0
stop = arg1
inc = arg2
elif arg1 is not None:#给定2个参数
start = arg0
stop = arg1
else:                 #给定1个参数
stop = arg0
result = []
while start <(stop-(inc/2.0)):
result.append(start)
start+=inc
return result

res = frange(3.0,5,1.0)
print(res)

#res [3.0, 4.0]


上述的代码是默认参数应用的例子,如果给定3个参数,第一个为开始,第二个为结束,第三个为步长。

”’文档”’ ,三个单引号或者三个双引号之间的为文档注释,它存在的意义是给定一个简单的总结说明。

可以看到,比较的时候用的is not None,而不是 !=None,在python中None的实例只有一个,因此,所有None的id(None)值都是一样的,is 比较的是地址,而!=None比较的是值,比较地址相对于从地址中取值再比较的速度是有优势的。

参数传递的都是对象的引用,但是因为字符串和整数的变量是不可变的,一个不可变参数的值在函数内发生了改变,该参数就会绑定到一个新的对象上,而它原先引用的对象则不会发生改变。

返回值和java不同的是,无需给定指定的类型,可以显式的return。非显式的就会返回None.

生成器函数

def frange(arg0,arg1=None,arg2=None):
'''类似于range()的浮点数生成器'''
start = 0.0
inc = 1.0
if arg2 is not None: #给定3个参数
start = arg0
stop = arg1
inc = arg2
elif arg1 is not None:#给定2个参数
start = arg0
stop = arg1
else:                 #给定1个参数
stop = arg0
result = []
while start <(stop-(inc/2.0)):
yield start
start+=inc

res = frange(3.0,5.0,1.0)
print(res)
for x in res:
print(x)

输出:
<generator object frange at 0x02BA7F80>
3.0
4.0


把return换成yield,就可以把函数转换成一个生成器。对于长列表,使用生成器的这种形式会更效率些,因为使用列表的那种形式会在内存中创建整个列表,而生成器每次只创建一个元素。yield和return语句比较相似,有个不同的是yield会接着上次的状态继续执行,如yield第一次返回是3.0,第二次返回的是4.0,那么3.0的状态依然存在。于是这个生产器包含的值是3.0和4.0.

res = frange(3.0,5.0,1.0)
print(res)
print(next(res))
print(next(res))
print(next(res))

输出:


res生成器中有3.0 4.0 ,当输出4.0后再次next(),就会报StopIteration异常。

res = frange(3.0,5.0,1.0)
for x in res:
print(x)
res = frange(3.0,5.0,1.0)
resl = list(res)
print(resl)

输出:
[3.0, 4.0]
[3.0, 4.0]


可以看到,列表的构造函数和for循环可以自动处理StopIteration异常

关键字参数的使用

def simplify(text, space=" \t\r\n\f", delete=""):
result = []
word = ""
for char in text:  # 遍历text
if char in delete:  # 判断字符是否在delete中 如果在则跳出本层循环
continue
elif char in space:  # 判断是否在space
if word:  # 如果word存在
result.append(word)  # 将word添加到列表
word = ""
else:
word += char  # 即不在delete,也不在space,拼接到word
if word:
result.append(word)
return " ".join(result)

print(simplify(' this   and\n that\t too')) #this and that too)
print(simplify(" Hello. world ",delete="."))#Hello world
print(simplify(delete="aed",text="sdeja")) #s j


上述代码的含义是去掉给定字符串的空格,或者指定需要删除的字符,在第一个调用中,simplify(’ this and\n that\t too’))我们使用了默认的space和delete参数,第二个调用中我们指定了一个关键字参数delete,使用了space默认参数,第三个调用我们给定两个关键字参数。可以看出,如果使用关键字参数,其参数的顺序由自己决定,但是如果使用了位置参数,那么位置参数的顺序要放在关键字参数的前面,如例二。

lambda函数

function = lambda x:pow(x,3)
print(function(2)) #8


lambda用来创建简单的匿名函数,它不能包含分支也不能包含循环,也没有return语句,其返回值仅仅是表达式计算后得到的值。如上述的代码就是计算x的3次方的值。

动态函数的创建

import sys
if sys.version_info[:2]<(2,4):
def sorted(items):
items = list(items)
items.sort()
return items


这段代码的含义是当python解释器的版本在2.4以下时,定义一个sorted()函数,因为sorted()函数是在python2.4中加入的。

sys.version_info是一个元组,其保存了当前使用的python解释器的版本,如:sys.version_info(major=3, minor=4, micro=4, releaselevel=’final’, serial=0),我目前使用的版本是3.4.4,[:2]是切片的操作,截取前两个元素与(2,4)比较,这里需要注意的是元组可以进行比较的操作,但前提是元组里面的元素可以比较。看下面这段代码:

print((2,3)<(4,5)) #True
print((2,3)<(1,4)) #False
print((2,3)<(1,2)) #False


上述的比较类似于 2<3 and 3<5 ,必须都满足条件返回的才是True.

偏函数

#偏函数的应用
def hello(who):
print('hello',who)
hello('me') #hello me


上述的代码,传进一个参数,并打印,现在我只想向自己问好,也就是说,我们确定了参数的值为me,现在想把函数和参数都封装到一起,组成一个可调用的对象,那么该如何改造呢?

def partial(func,arg):
def callme():
return func(arg)
return callme

def hello(who):
print('hello',who)

f1=partial(hello,'me')
f1()

输出:hello me


partial有两个参数,一个是要调用的函数的引用,一个是要调用函数的参数。在上面的例子中,partial(hello,’me’)返回相当于返回的是hello(‘me’)的hello.传给f1,f1()调用.

import functools
def hello(who):
print('hello',who)

f1=functools.part
b776
ial(hello,'me');

输出:hello me


这里python为我们提供了一个工具functools,可以直接实现函数和参数绑定的操作

总结:

我们讲了函数的定义,
def f(参数1,参数2,...)
,f中存储的是函数对象的引用,
f()
加个括号为调用该函数,我们也可以这样操作
g=f;g()
,这样也可以调用函数。

默认参数,
def f(参数1,参数2=2)
,默认参数存在的情况下,调用函数可以只传不带默认参数的值,如
f(1)
,这里需要注意的是,定义带默认值的函数时,带默认值的参数要放在不带默认值参数的后面。

is not None
,is not比较的是内存中的地址,
==
比较的是地址中的值,比较地址比比较值要快一些,因为比较值要先从地址中取值。
None
对象是全局变量,在python中只存在一个。

生成器函数, 将函数中的
return
换成
yield
就可,生成器的优点在于可以不用一次性生成很多值来占用内存,并且在需要的时候才会生成对应的值。生成器遍历完成再次next()会出现stopIteration异常,欣慰的是for循环和list的构造函数可以自动的处理它。

关键字参数是将参数名+参数值传给函数,如def f(a,b) 调用的时候这样传参 f(b=2,a=1),关键字参数间可以随意的更改参数的位置,如f(a=1,b=2),但是如果有位置参数的话,关键字参数要放在位置参数的后面。

匿名函数用关键字lambda来定义,它只能有一些简单的语句,不能包含return ,循环,分支结构。
f=lambda x:pow(x,3)


动态函数的创建:动态函数就是在某些条件满足的条件下,再创建函数

偏函数:我们想让函数和其参数绑定起来,python提供的工具
functools.partial(func,param)
可以实现这一要求。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息