Python 嵌套函数、装饰器、特殊函数(lambda、map、filter)

1 函数基础

1.1 定义函数

在这里插入图片描述
定义函数

def hanshu(a,b):
    c = a + b 
    return c
hanshu(3,5)
8

例:大小写转换

def convert(s):
    lst = [i.upper() if i==i.lower() else i.lower() for i in s]
    return "".join(lst)

s = "Hello"
c = convert(s)
print(c)

函数调用的三个特征按照位置提供参数

1.2 定义函数的三个特征:按照位置提供参数、指定参数名称、设置参数默认值

def hanshu(x,y):
    print('x is',x)
    print('y is',y)
    
hanshu(2,3)
x is 2
y is 3
hanshu(x = 3, y = 4)
x is 3
y is 4
hanshu(y = 4 , x = 3) #按照位置提供参数可以不使用默认顺序
x is 3
y is 4

指定默认参数,只能写在后面,写在前面要报错

def hanshu(x,y=3): #y在默认情况下为3
    print('x is',x)
    print('y is',y)
    
hanshu(2)
x is 2
y is 3
hanshu(2,5):    #y在默认情况下为3,修改后则为指定数
x is 2
y is 5

1.3 返回值

必须用return语句接受返回值
return可以返回多个值,自动组装成元祖

def hanshu():
    return 1,2,3
r = hanshu() #一对多
r
(1, 2, 3)
a,b,c = hanshu()  #多对多
a,b,c
(1, 2, 3)

1.4 参数收集“*”

一个“*” :代表任意数量

def hanshu(x,*y):
    print("x = ",x)
    print("y = ",y)
    
hanshu(1,3,4,5)
x =  1
y =  (3, 4, 5)

def hanshu(x,y): #如果不加*,二对多会报错
    print("x = ",x)
    print("y = ",y)
    
hanshu(2,34,5,3)  
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: hanshu() takes 2 positional arguments but 4 were given

两个“*”:代表字典对应关系

def hanshu(x,**y):
    print("x = ",x)
    print("y = ",y)
    
hanshu(1,a=3,b=3,c=5)
x =  1  
y =  {'a': 3, 'b': 3, 'c': 5}

案例:数据:d = {‘a’:39,‘b’:50,‘c’:90,‘d’=100},对该字典中键值对进行查询,例如提供a = 1,b = 50等参数,查询是否为数据d内的值

def findkv(dct, **kawargs):
    r = {k:v for k, v in kawargs.items() if dct.get(k) == v}
    return r

d = {'a':39,'b':50,'c':90,'d':100}
fr = findkv(d,a=1,b=50)
print(fr)

runfile('H:/pythonProject/main.py', wdir='H:/pythonProject')
{'b': 50}

2 嵌套函数和装饰器

2.1 引用

def foo(a):
    a.append(99) #定义了一个增加99的函数,该函数必须支持append,否则会报错
    return a
    
lst = [1,2,3]
lst.append(0)
lst
[1, 2, 3, 0]

foo(lst)
[1, 2, 3, 0, 99] 
 def bar():
    print('i am pig')
    
bar() #带括号,是引用函数,执行对象,无非有没有参数
i am pig

bar #不带括号,是函数本身的内存地址,说明函数本身也是对象
<function bar at 0x7fb4102bd320>

3() #整数不可执行callable,所以报错
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'int' object is not callable

```python
def bar():
    print('i am pig')
    
def foo(f): 
    f() #这个函数必须执行
foo(bar)
i am pig

foo(str)
str
<class 'str'>
str()
''

foo(3) #不可执行则报错
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 2, in foo
TypeError: 'int' object is not callable

总结:函数是个对象,定义函数可以引用任意一个对象

def opt_seq(func,seq): 
    r = [func(i) for i in seq] #func(i) 表示func这个参数必须支持被引用,比如求绝对值abs()
    return r 
abs(-2)
2
opt_seq(abs,range(-5,5))
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]

opt_seq(ord,'python') #‘python字符串内自负的ascii码’
[112, 121, 116, 104, 111, 110]

2.2 嵌套

只在函数内定义函数,但没有引用

def foo():
    def bar():
        print('i am bar')
    print('i am foo')
    
foo()
i am foo 

在函数内不定义函数,并且引用

def foo():
    def bar():
        print('i am bar')
    print('i am foo')
    bar()
    
foo()
i am foo
i am bar

但这种函数没法在外面实用

def foo():
    def bar():
        print('i am bar')
    return bar #返回bar(bar本身已经被定义)
a = foo() #即a =bar
a()  #a() = bar()
i am bar

bar() #报错,因为作用域没这么大,bar()的作用域仅限于foo里面

关于作用域、全局变量、局部变量、全局声明(global,nonlocal)

a = 1   #这里的a是全局变量
def haha():
    print(a+1)
    
haha()
2
a =1 
def haha():
    a = a + 1 #这里的a是局部变量,因此会报错
    print(a)
    
haha()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 2, in haha
UnboundLocalError: local variable 'a' referenced before assignment

def haha():
    global a #a是全局变量的声明
    a = a + 1
    print(a)
    
haha()
2

案例:计算重力加速值,G=mg,定义一次重力加速度,然后计算不同质量m的G

def weight(g):
    def cal_mg(m):
        return m * g
    return cal_mg

w = weight(10)  #w= weight(10)
G = w(100)    #G = weighe(10)函数内m为100的情况
G1 = w(40)

2.3 装饰器

装饰器相当于嵌套函数的简写
只需调用被装饰的对象
关于.format()函数的说明

>>>"{} {}".format("hello", "world")    # 不设置指定位置,按默认顺序
'hello world'
 
>>> "{0} {1}".format("hello", "world")  # 设置指定位置
'hello world'
 
>>> "{1} {0} {1}".format("hello", "world")  # 设置指定位置
'world hello world'
def p_deco(func):
    def wrapper(name):
        return "<p>{0}</p>".format(func(name))
    return wrapper

def book(name):
    return "the name of my book is {0}".format(name)

laoqi = p_deco(book)
py_book = laoqi("Python大学实用教程")

print(py_book)

在这里插入图片描述

利用@p_deco进行装饰,不用重复引用,代码更简洁

def p_deco(func):
    def wrapper(name):
        return "<p>{0}</p>".format(func(name))
    return wrapper

@p_deco
def book(name):
    return "the name of my book is {0}".format(name)

# laoqi = p_deco(book)
# py_book = laoqi("Python大学实用教程")

py_book = book("Python大学实用教程")
print(py_book)

案例:测试函数执行时间

import time

def timing_func(func): #定义函数,记录并返回函数执行前后的时间
    def wrapper():
        start = time.time()
        func()
        stop = time.time()
        return stop - start
    return wrapper

@timing_func #装饰器,for循环
def test_list_append():
    lst = []
    for i in range(1000000):
        lst.append(i)

@timing_func #装饰器,列表解析
def test_list_compre():
    [i for i in range(1000000)]

a = test_list_append()
b = test_list_compre()
print("test list append time:", a)
print("test list comprehension:", b)

test list append time: 0.07764887809753418
test list comprehension: 0.039337873458862305

3 特殊函数

lambda、map、filter
调用方法、实现功能、性能等与普通函数有区别

3. 1 lambda (不用使用def)

def add(x):
    x += 3
    return x
add(3)
6

lam = lambda x : x+3
lam
<function <lambda> at 0x7f77f01ba170>
lam(3)
6

3.2 map函数(对可迭代对象分别使用表达式)

m = map(lambda x : x +3, range(10)) #得到0-9分别+3的值
m
<map object at 0x7fce1024add0>
list(m)
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]


lst1 = [1,2,3,4]
lst2 = [2,3,4,5]
[x+y for x,y in zip(lst1,lst2)] #列表循环
[3, 5, 7, 9]
r = map(lambda x,y:x+y,lst1,lst2) #使用lamda函数和map
list(r)
[3, 5, 7, 9]

3.3 filter

从函数中依据一定条件提取对象

a = range(-5,10)
f = filter(lambda x:x>0,a)
f
<filter object at 0x7fce102645d0>
list(f)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值