Python 函数浅析

函数定义和使用:

def 函数名(形参列表):    

    函数体

    [return [返回值]]

查看Python中所有的关键字(33个)

>>> import keyword

>>> keyword.kwlist

['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

形参列表:

a,b,c

addr='BeiJing'

可变参数:

*args        -> 在函数中以元组的形式组织的

**kwargs    -> 在函数中以字典形式组织的

def f1(name,addr='BeiJing',*args,**kwargs):
print(name,addr,args,kwargs)
# 不推荐使用,addr默认值参数起不到作用.

def f2(name,*args,addr='BeiJing',**kwargs):
print(name,addr,args,kwargs)

f2('Andy',1,2,3,addr='tianjin',email='abc@abc.com')

 

函数的使用:

 

使用返回值:

    直接打印:print(add(1,2))

    把一个函数的调用,当成另一个函数的参数

    sum(add(1,2),add(3,4))

不使用返回值:单独调用:直接函数名(参数),不关心函数的返回值.

 

函数名当成函数的返回值:

通常发生在函数嵌套定义中:

def outer():

    def inner():

        ....

    return inner            # 返回内层函数的定义,是一个地址

 

函数是一等公民!

函数的地位和变量一样,可以当成参数传递,可以给变量赋值.

 

高阶函数

可以接收一个函数作为参数的函数,称为高阶函数.

 

def func(f):        # 当f是一个函数时,func就称为高阶函数.

    pass

    

 

Python中常见的高阶函数:

map(key=)

filter(key=)

sorted(key=)

 

lst=[-1,2,-3,4]

def f(x):
return abs(x)

# res = map(f,lst)
# for x in res:
# print(x)

 

 

filter函数如果不指定功能参数,默认使用bool(x)操作每一个元素!用以获取一个布尔值.

def f2(x):
if x > 0:
return True
elif x < 0:
return False

f = filter(f2,lst)
for x in f:
print(x)

 

 

为了替换高阶函数中参数函数的繁琐定义,使用lambda表达式!!!

f = filter(lambda x:True if x >= 0 else False,lst)

 

lambda表达式最主要的使用场景:和高阶函数配合使用,充当高阶函数的参数!!!

 

lst = [2,1,5,9]

res = sorted(lst)

sorted是形成了一个新的排序后的结果,通常会赋值给一个变量.

 

 

高阶函数的替代者:推导式

列表推导式:

res = [包含了变量的表达式 for 变量 in 可迭代对象]

 

用来替换map函数:

前面的包含了变量的表达式就是map中的业务逻辑

可迭代对象就是map中的数据源

 

filter

res = [满足条件的元素 for 变量 in 可迭代对象 if条件判断]

filter业务逻辑使用if来实现

数据源来自可迭代对象

 

推导式种类:

列表推导式:

[]

字典推导式

{:}

集合推导式

{}

 

没有元组推导式,用()括起来的是:生成器表达式.

 

 

如何查看一个包,类中所有可用的方法(属性):

[x for x in dir(json) if not x.startswith('_')]

[x for x in dir(os) if not x.startswith('_')]

[x for x in dir(sys) if not x.startswith('_')]

[x for x in dir(time) if not x.startswith('_')]

[x for x in dir(list) if not x.startswith('_')]

[x for x in dir(tuple) if not x.startswith('_')]

[x for x in dir(set) if not x.startswith('_')]

[x for x in dir(dict) if not x.startswith('_')]

 

练习:把目前见到的包,常见的数据类型中可用的方法通过上述方式查到.

查看某个具体方法的使用:

help(类名)    help(list)

help(类名.方法名)        help(list.pop)

 

 

Python中三大神器!

 

迭代器:iterator

可迭代对象:iterable

从表现形式上看:能使用for循环迭代的,就是可迭代对象!

    字符串,列表,字典,集合,元组.

它们都有一个方法:__iter__,魔法方法,推荐使用iter(x)

iter(x) -> 得到的是一个绑定到当前可迭代对象身上的迭代器!!!

 

for循环实际上干了两件事:

1.获取可迭代对象的迭代器.

2.通过迭代器遍历可迭代对象!!!

 

迭代器:实现了__iter__,__next__方法的对象(也称为实现了迭代器协议.),就是迭代器.

这两个方法是魔法方法(Python中不推荐直接使用的),推荐使用替代方法:

iter(x)        -> 返回的就是这个迭代器本身.

next(x)        -> 返回的是下一个可用元素.

 

lst = [1,2,3]

# 获取到迭代器对象

i = iter(lst)

# 使用迭代器的next方法,依次获取元素

print(next(i))

print(next(i))

 

手动使用next方法有个缺点:没有办法很好的控制边界!!!

使用for循环可以自动判定边界.

 

可迭代对象和迭代器的关系:

 

可迭代对象每次调用iter方法,获取的都是新的迭代器.

 

如何验证一个对象是可迭代的?还是迭代器?

from collections import Iterator,Iterable

print(isinstance([1,2,3],Iterable))    True
print(isinstance([1,2,3],Iterator))    False

 

 

 

 

生成器:generator

一种流式生成数据的方式:

流式产生数据:保存的不是真实的数据,而是产生数据的方式!!

 

好处:节省内存!!!!

 

自定义生成器(函数):

包含了yield关键字的函数,就是生成器函数.

 

def my_generator():

    yield 10

 

 

def my_generator():

    for x in range(100):

        yield x

 

 

生成器本质上就是迭代器:

# 借助collections包中的Iterator类,
from collections import Iterator,Iterable
print(isinstance(g,Iterator))

# 既然是迭代器,就使用for循环迭代!!
for x in g:
print(x)

 

for循环本质上就是调用生成器的next方法,即:

第一种触发生成器的方式:使用next方法!!!

 

 

带有赋值语句的生成器:

 

第一次比较特殊:只执行一,三部分

从第二次开始:一,二,三执行.

...

 

 

第二种触发生成器的方式:使用send方法.

 

 

根据定义时是否有赋值语句,以及两种触发方式:一共有四种组合!!!

1.没有赋值语句,使用next触发

def my_generator():
for x in range(5):
yield x

g = my_generator()
print(next(g))
print(next(g))
print(next(g))
print(next(g))

 

 

 

2.没有赋值语句,使用send触发

def my_generator():
for x in range(5):
yield x

g = my_generator()
print(g.send(None))
print(g.send(10))
print(g.send(20))
print(g.send(30))

 

由于没有变量接收,传递的值,实际上都丢弃了!!!

 

 

3.有赋值语句,使用next触发

 

# 有赋值语句,使用next触发
def my_generator(n):
for x in range(n+1):
n = yield x
print(n)


g = my_generator(5)
print(next(g))
print(next(g))
print(next(g))

 

由于没有使用send,使用next方法,实际上每次都是传递的None

 

4.有赋值语句,使用send触发

def my_generator(n):
total = 0
for x in range(n+1):
n = yield total
total += n

g = my_generator(5)
print(g.send(None))
print(g.send(1))
print(g.send(2))
print(g.send(3))
print(g.send(4))

 

计算移动平均值!

def my_generator(n):
total = 0
count = 0
avg = 0
for x in range(n+1):
n = yield avg
total += n
count += 1
avg = total / count


g = my_generator(5)
print(g.send(None))
print(g.send(10))
print(g.send(20))
print(g.send(30))
print(g.send(40))

 

 

装饰器:decorator

对原函数进行功能上的增强!

 

def wrapper(fn):
# return fn

# 定义嵌套函数,
def inner(*args,**kwargs):
# 对原始函数的调用
ret = fn(*args,**kwargs)
# 对原始函数的返回值进行处理
if ret < 0:
return -ret
else :
return ret

# 把嵌套函数返回
return inner

@wrapper
def func(a,b):
return a - b


print(func(5,3))
print(func(5,30))

 

 

 

# 定义装饰器
def w(min_value,max_value):
def wrapper(fn):
# return fn

# 定义嵌套函数,
def inner(*args,**kwargs):
# 对原始函数的调用
ret = fn(*args,**kwargs)
# 对原始函数的返回值进行处理
if ret < min_value:
return min_value
elif ret > max_value:
return max_value

# 把嵌套函数返回
return inner

return wrapper


@w(-5,5)
def fun(a,b):
return a + b

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/liangsha0/p/10593702.html