Python 零基础入门到实战(二)笔记:加法、大小写转换、查询键值对、重力案例、装饰器、特殊函数:lambda、map、filter

这篇博客深入探讨了Python函数的基础,包括定义、调用、参数传递方式(位置、名称、默认值、收集参数)、返回值(单个与多个)、作用域以及装饰器的概念。通过实例展示了如何使用装饰器来测试函数执行时间,并解释了lambda、map和filter函数的用途。此外,还讨论了Python中函数作为对象的特性,如函数嵌套和闭包。文章以重力案例结尾,演示了如何利用装饰器根据不同的重力值调整计算结果。
摘要由CSDN通过智能技术生成

Part 4 Python函数基础

函数定义:

def function_name(x,y,z):
[ 空四格 ]do sth. return object

最简单,以写一个加法函数为例:

>>> def add(x,y):
...     r=x+y
...     return r

结果:

>>> add(2,3)
5

函数调用:

在第一篇笔记中有一个转化大小写的小案例,在这里用函数方法进行调用,代码如下

def convert(s):
    lst=[i.upper() if i.islower() else i.lower() for i in s]//列表解析
    return "".join(lst)

while(True):
    s=input("input a word:")
    if s!='exit':
        r=convert(s)
        print(r,"inputing 'exit' is the end of the pro")
    else:
        break
print("end of project")
input a word:Apple
aPPLE inputing 'exit' is the end of the pro
input a word:In
iN inputing 'exit' is the end of the pro
input a word:exit
end of project

按位置提供参数:

与其他编程语言同

指明参数名称:

注意:python中可指明参数名称传参,这是与C/C++不同的,例如

>>> def add(x,y):
...     print('x=',x)
...     print('y=',y)
...
>>> add(2,3)
x= 2
y= 3
>>> add(y=2,x=3)
x= 3
y= 2

函数定义时,声明默认值同C++一样,需放在最后、如:

>>> def add(x,y=2):
...     print('x=',x)
...     print('y=',y)
>>> add(1)
x= 1
y= 2

返回一个值/返回多个值:

函数中可返回多个值,会自动成一个元组

若用多个对象接受,则每个对象对应相应的值

很牛,头一回见到那么灵活的语言

参数收集:

一个*

*是一个标记

>>> def test(x,*y):
...     print('x:',x)
...     print('y:',y)
...
>>> test(1,2,3,4,5)
x: 1
y: (2, 3, 4, 5)

两个*

>>> def test1(x,**y):
...     print('x:',x)
...     print('y:',y)
...
>>> test1(1,a=2,b=3,c=4)
x: 1
y: {'a': 2, 'b': 3, 'c': 4}

案例:查询键值对:

假设有数据:d={‘a’:39,‘b’:40,‘c’:99,‘d’:100}(字典的键值对还可以增加)编写函数实现对这个字典中的键值对的查询,例如向函数提供a=1,b=40等参数,查询是否为此数据的值

def check(tar,**tarkv):
    r = {k:v for k,v in tarkv.items() if tar.get(k)==v}
    return r
d={'a':39,'b':40,'c':99,'d':100}
fr=check(d,a=90,b=40,c=99,d=100)
print(fr)
{'b': 40, 'c': 99, 'd': 100}

层层嵌套:

函数本身就是对象,故可以函数套函数

>>> def opt_seq(func,seq):
...      r=[func(i) for i in seq]
...      return r
...
>>> opt_seq(abs,range(-5,5))
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
>>> opt_seq(str,[1,2,3])
['1', '2', '3']
>>> opt_seq(ord,'python')
[112, 121, 116, 104, 111, 110]
>>> def foo():
...     def bar():
...         print("I am bar")
...     return bar
...
>>> a=foo()
>>> a()
I am bar
>>> a
<function foo.<locals>.bar at 0x00000140AEABA040>
>>> bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined

调用了foo()函数,返回了bar函数的地址并赋给了a
故输入a()等于调用了bar()
但是直接调用bar()的话就会失败、因为bra()在foo()中,不能直接调用

作用域问题:

如果在想在函数定义里用全局变量,在前加上global即可;
如下代码,会导致错误:

>>> a=1
>>> def test1():
...     a+=1
...     return a
...
>>> test1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test1
UnboundLocalError: local variable 'a' referenced before assignment

test1函数中就报错了,试试在a前加上global即可

>>> a=1
>>> def test1():
...     global a
...     a+=1
...     return a
>>> test1()
2

如果再函数中函数要用函数中的变量,在函数中的函数里的变量前加上nonlocal 即可

>>> def func():
...     b=1
...     def func1():
...         nonlocal b
...         b+=1
...         print(b)
...     return func1
...
>>> c=func()
>>> c()
2

重力 案例

def w(m,g):
    return m*g

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

w=weight(10) #取g=10
G=w(100)
G2=w(50)
print(G," ",G2)

w2=weight(9.78046)
G1=w2(100)
print(G1)

结果:

1000   500
978.0459999999999

因为在地球不同的地方,受维度不同,重力不同
故将函数这样写,先定weight,返回cal_mg()的地址
之后通过接收的对象例如w,w2,即可调用、同时g已经确定好了。在实际编程中是一个不错的思路

装饰器:

过了一遍视频,写法很妙,理解不深,后续在做研究、

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

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

brian=p_deco(book)
py_book=brian("python学习")
print(py_book)
<p>the name of my book is python学习</p>

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

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

@div_deco
@p_deco

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

# brian=p_deco(book)
# py_book=brian("python学习")
py_book=book("python学习")
print(py_book)

运行结果

<div><p>the name of my book is python学习</p></div>

编写一个用于测试函数执行时间的装饰器函数 案例

import time
def timing_func(func):
    def wrapper():
        start = time.time()
        func()
        stop = time.time()
        return stop - start
    return wrapper
@timing_func
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()
c = test_list_compre()
print("test list append time:", a)
print("test list comprehension time:", c)
print('append/compre =', round(a/c, 3))
test list append time: 1.7951829433441162
test list comprehension time: 0.833770751953125
append/compre = 2.153

如何编写更通用的的测试函数执行时间的装饰器?后续学习改进

特殊函数

能用先用,不能用先放一边。用得好,出彩,用不好,会带来不少麻烦、

lambda

lambda的主体是一个表达式,而不是一个代码块。能在lambda表达式中封装有限的逻辑进去

>>> def add(x,y):
...     return x+y
...
>>> add(2,3)
5
>>> lam=lambda x,y:x+y
>>> lam
<function <lambda> at 0x000001F2EA5D0D30>
>>> lam(2,3)
5

map

根据提供的函数对指定序列做映射

class map(object)
 |  map(func, *iterables) --> map object
 |
 |  Make an iterator that computes the function using arguments from
 |  each of the iterables.  Stops when the shortest iterable is exhausted.
>>> lst1=[1,2,3,4,5]
>>> lst2=[1,2,3,4,5]
>>> lst3=[1,2,3,4,5]
>>> [x+y+z for x,y,z in zip(lst1,lst2,lst3)]
[3, 6, 9, 12, 15]
>>> r=map(lambda x,y,z: x+y+z,lst1,lst2,lst3)
>>> list(r)
[3, 6, 9, 12, 15]

filter

实现过滤功能如从–5到4中筛选出>0的数

class filter(object)
 |  filter(function or None, iterable) --> filter object
 |
 |  Return an iterator yielding those items of iterable for which function(item)
 |  is true. If function is None, return the items that are true.
>>> [i for i in range(-5,5) if i>0]
[1, 2, 3, 4]
>>> a=filter(lambda x:x>0,range(-5,5))
>>> a
<filter object at 0x000001F2EAC08DF0>
>>> list(a)
[1, 2, 3, 4]
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会写程序的程序员.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值