【python零基础入门学习】python进阶篇之高阶函数

news2024/11/19 9:18:58

 本站以分享各种运维经验和运维所需要的技能为主

《python零基础入门》:python零基础入门学习

《python运维脚本》: python运维脚本实践

《shell》:shell学习

《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战

《k8》暂未更新

《docker学习》暂未更新

《ceph学习》ceph日常问题解决分享

《日志收集》ELK+各种中间件

《运维日常》运维日常

《linux》运维面试100问

高阶函数应用

用法:

函数操作符:

参数:

  • 以key=val形式存在的参数,称为关键字参数

  • 以args形式存在的参数,称作位置参数

def func1(name,age):
    print('%s is %s years old' % (name,age))
    
    
func1() #报错, 参数不够
func1('tom',20,100) #错误,参数个数太多
func1('tom',20) #OK

func1(20,'tom') #语法正确,语义不对

func1(age=20,name='ton') #OK
func1(age=20,'tom') #语法错误.关键字参数必须在位置参数后

func1(20,name='tom') #错误,因为name得到了多个值

func1('tom',age=20) #ok

参数组:

  • 定义函数时,参数名前加上*表示把参数放到元组中

  • 定义函数时,参数名前加上(两个)**表示把参数放到字典中

将参数放到元组上:  加 *
def func2(*args):
    print(args)
    
func2()
func2('hao')
func2('hao',100,200,'tom','jerry')

>>> func2()
()
>>> func2('hao')
('hao',)

将参数放到字典上 :  加**
>>> def func(**args):
...     print(args)
... 
>>> 
>>> func()
{}
>>> func(name='tom',age=20)
{'name': 'tom', 'age': 20}



 例子:

调用函数时,给参数加上一个*把列表拆成一个个的个体:

>>> def myadd(x,y):
...     return x + y
... 
>>> 
>>> nums = [123 , 4564]
>>> myadd(nums[0],nums[1])
4687
>>> myadd(*nums)
4687

调用函数时,给参数加上一个*把拆成一个个的个体:

>>> def myadd(x,y):
...     return x + y

>>> adict = {'x':100,'y':25}
>>> adict
{'x': 100, 'y': 25}
>>> myadd(**adict)
125

myadd(x=100,y=25)

计算游戏:

from random import choice,randint

def exam():
    '出题测试'
    #随机取出100以内的两个随机数字
    nums = [randint(1,100) for i in range(2)]
    nums.sort(reverse=True) #降序排列


    #随机取出加减法
    op = choice('+-')


    #算出正确答案
    if op == '+':
        result = nums[0] + nums[1]
    else:
        result = nums[0] - nums[1]


    #用户作答
    count = 0
    win = 0
    prompt = '%s %s %s = ' % (nums[0], op, nums[1])
    while count < 4:
        try:
            answer = int(input(prompt))
        except ValueError:
            print('不可以偷懒哦')
            continue
        if answer == result:
            win += 1
            print('Very Good !!!')
            break
        else:
            print('Wrong Answer !!!!')
        count += 1
    else:
        print('\033[031;1m正确答案:%s%s\033[0m' % (prompt,result))

def main():
    while 1:
        exam()
        try:
            #将用户输入信息的额外空白字符删除后,取出第一个字符
            yn = input('Continue(y/n)? ').strip()[0]
        except IndexError:
            continue
        except (KeyboardInterrupt, EOFError):
            print('n')

        if yn in 'nN':
            print('\nbye-bye')
            break



if __name__ == '__main__':
    main()

匿名函数:

  • lambda关键字后面的名称是函数参数

  • 冒号后面表达式的结果是匿名函数的返回值

>>> add2 = lambda x,y : x+y

>>> add2(5,6)
11


from random import choice,randint

# def add(x,y):
#     return x + y
#
# def sub(x,y):
#     return x - y

def exam():
    '出题测试'
    #cmds = {'+': add, '-': sub}
    cmds = {'+': lambda x, y:x + y, '-':lambda x, y: x - y}
    #随机取出100以内的两个随机数字
    nums = [randint(1,100) for i in range(2)]
    nums.sort(reverse=True) #降序排列


    #随机取出加减法
    op = choice('+-')


    #算出正确答案
    # if op == '+':
    #     result = nums[0] + nums[1]
    # else:
    #     result = nums[0] - nums[1]
    #result = cmds[op](nums[0],nums[1])
    result = cmds[op](*nums)

    #用户作答
    count = 0
    win = 0
    prompt = '%s %s %s = ' % (nums[0], op, nums[1])
    while count < 4:
        try:
            answer = int(input(prompt))
        except ValueError:
            print('不可以偷懒哦')
            continue
        if answer == result:
            win += 1
            print('Very Good !!!')
            break
        else:
            print('Wrong Answer !!!!')
        count += 1
    else:
        print('\033[031;1m正确答案:%s%s\033[0m' % (prompt,result))

def main():
    while 1:
        exam()
        try:
            #将用户输入信息的额外空白字符删除后,取出第一个字符
            yn = input('Continue(y/n)? ').strip()[0]
        except IndexError:
            continue
        except (KeyboardInterrupt, EOFError):
            print('n')

        if yn in 'nN':
            print('\nbye-bye')
            break



if __name__ == '__main__':
    main()

filter函数

  • 它的第一个参数是函数,该函数接受一个参数,返回True或者False

  • 它的第二个参数是序列对象

  • 序列对象的每个值作为参数传给第一个函数,返回真保留,否则丢弃

过滤奇数:
from random import randint

def func1(x):
    return  True if x % 2 == 0 else False

if __name__ == '__main__':
    nums = [randint(1,100) for i in range(10)]
    print(nums)
    result = filter(func1,nums)
    result2 = filter(lambda x:True if x % 2 == 0 else False,nums)
    print(list(result))
    print(list(result2))

 

map函数:

  • - 它的第一个参数是函数,该函数用于加工数据

  • - 它的第二个参数是序列对象

  • - 序列对象中的每一个数据都会传给函数进行加工,保留加工结果

from random import randint

def func(x):
    return x * 2 +1

if __name__ == '__main__':
    nums = [randint(1,100) for i in range(10)]
    print(nums)
    result = map(func,nums)
    result2 = map(lambda x: x * 2 + 1 , nums)
    print(list(result))
    print(list(result2))

 

变量作用域:

全局变量:#在函数外面定义的变量,是全局变量,全局变量从定义开始,到程序结束,一直可见可用

局部变量:#函数内定义的变量是局部变量,局部变量只能在函数内使用


#在函数外面定义的变量,是全局变量,全局变量从定义开始,到程序结束,一直可见可用
>>> a = 100
>>> def func1():
...     print(a)
... 
>>> func1()
100

#函数内定义的变量是局部变量,局部变量只能在函数内使用
>>> def func2():
...     b = 'hello'
...     print(b)
... 
>>> func2()
hello
>>> b #全局变量中,b变量还没有定义
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined

#全局和局部存在同名变量,局部变量将会遮盖住全局变量
>>> def func3():
...     a = 200
...     print(a)
... 
>>> func3()
200
>>> a
100

#如果希望在局部将全局变量改变,需要使用global关键字
>>> def func4():
...     global a 
...     a = 200 
...     print(a)
... 

>>> func4()
200
>>> print(a)
200
>>> a
200

偏函数:

  • - 改造现有函数,生成新函数

  • - 将现有函数的某些参数固定下来,生成新函数

>>> def add(a,b,c,d,e):
...     return a + b + c + d + e
... 
>>> add(10,20,30,40,1)
101
>>> add(10,20,30,40,9)
109
>>> add(10,20,30,40,19)
119

#改造现有的add函数,把前4项的值固定来,生成新函数,新函数只需要一个参数,即原函数的第5个参数
>>> from functools import partial
>>> myadd = partial(add,10,20,30,40)
>>> myadd(1)
101
>>> myadd(9)
109
>>> myadd(19)
119

#int函数默认认为传入的字符串是10进制数形式
>>> int('10')
10
>>> int('10',base=2)
2
>>> int('11',base=2)
3
>>> int('11000001',base=2)
193

#改造int函数,生成新函数intX,用于指字符串是X进制
>>> int2 = partial(int , base=2)
>>> int2('11110001')
241

>>> int8 = partial(int , base=8)
>>> int8('11')
9

 递归函数

def func(x):
    if x == 1:
        return 1
    else:
        return x * func(x - 1)


if __name__ == '__main__':
    print(func(5))

 例子:快速排序:

>>> nums = [11, 50, 51, 54, 57, 88, 68, 2, 81, 89]
# 假设第一个数是中间值,比中间值大的放到一个列表,小的放到另一个列表
>>> middle = nums[0]   # middle是数字
>>> smaller = [2]
>>> larger = [50, 51, 54, 57, 88, 68, 81, 89]
# 把3个部分拼接
>>> smaller + [middle] + larger
[2, 11, 50, 51, 54, 57, 88, 68, 81, 89]
# 继续用相同的方法把smaller列表和larger列表进行排序
# 当列表只有一项或是空列表,就不用再排序了

from random import randint
def qsort(seq):
    # 如果序列长度小于2,直接返回,不用排
    if len(seq) < 2:
        return seq
    # 假设第一项是中间值
    middle = seq[0]
    smaller = []  # 存放比中间值小的数字
    larger = []   # 存放比中间值大的数字
    # 遍历seq中剩余内容,比middle小的放到smaller中,大的放到larger中
    for data in seq[1:]:
        if data <= middle:
            smaller.append(data)
        else:
            larger.append(data)
    # 将三个部分拼接起来,smaller和larger用相同的方法继续排列
    return qsort(smaller) + [middle] + qsort(larger)
if __name__ == '__main__':
    nums = [randint(1, 100) for i in range(10)]
    print(nums)
    print(qsort(nums))

生成器:

  • 生成器表达式,与列表解析语法一样,只是用()替代[]

  • 函数形成的生成器

1.表达式:
>>> ['192.168.1.%s' % i for i in range(255)]
>>> ('192.168.1.%s' % i for i in range(255))  ----节省空间
<generator object <genexpr> at 0x7f79ed4c4b48>

>>> for ip in ('192.168.1.%s' % i for i in range(255)):
>>>     print(ip)

2.函数:
>>> def mygen():
...     yield 10
...     yield 200
...     a = 100 + 200
...     yield a
...     yield 'hello'
... 
>>> mg = mygen()
>>> mg
<generator object mygen at 0x7f79ed4c4ba0>
>>> for i in mg :
...     print(i)
... 
10
200
300
hello

模块:

搜索路径:

在导入模块时,python到sys.path定义的目录下搜索

(nsd1907) [root@room8pc16 day03]# mkdir /tmp/mymods
(nsd1907) [root@room8pc16 day03]# vim /tmp/mymods/star.py
hi = "Hello World!"
def pstar(n=30):
    print('*' * n)
if __name__ == '__main__':
    pstar()
(nsd1907) [root@room8pc16 day03]# python
>>> import star   # 报错
>>> import sys
>>> sys.path
>>> sys.path.append('/tmp/mymods')
>>> import star   # 成功

- 还可以定义PYTHONPATH环境变量,来指定模块搜索路径 

(nsd1907) [root@room8pc16 day03]# export PYTHONPATH=/tmp/mymods
(nsd1907) [root@room8pc16 day03]# python
>>> import sys
>>> sys.path
['', '/tmp/mymods', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/root/nsd1907/lib/python3.6/site-packages']

- 目录也可以作为一个特殊的模块,称作包

> 注意:在python2中,目录下必须有一个名为\_\_init\_\_.py的文件,才能成为包,该文

件即使是空的,也必须存在。

(nsd1907) [root@room8pc16 day03]# mkdir mypkgs
(nsd1907) [root@room8pc16 day03]# vim mypkgs/mytest.py
hi = 'Hello China'
(nsd1907) [root@room8pc16 day03]# ls
mypkgs
(nsd1907) [root@room8pc16 day03]# python
>>> import mytest   # Error
>>> import mypkgs.mytest   # 正确
>>> mypkgs.mytest.hi
'Hello China'

 

tarfile模块

  • 用于实现压缩,解压缩

打包:
>>> tar = tarfile.open('/tmp/myfile.tar.gz', 'w:gz')
>>> tar.add('/etc/hosts')
>>> tar.add('/etc/security')
>>> tar.close()
解压:
>>> tar = tarfile.open('/tmp/myfile.tar.gz')
>>> tar.extractall(path='/tmp/mymods')
>>> tar.close()
>>>

 hashlib模块:

(nsd1907) [root@room9pc01 etc]# echo -n 123456 > /tmp/1.txt
(nsd1907) [root@room9pc01 etc]# md5sum /tmp/1.txt 
e10adc3949ba59abbe56e057f20f883e  /tmp/1.txt

>>> import hashlib
>>> m = hashlib.md5(b'123456')     #参数必须是bytes类型
>>> m.hexdigest()
'e10adc3949ba59abbe56e057f20f883e'

>>> m1 = hashlib.md5()
>>> m1.update(b'12')
>>> m1.update(b'34')
>>> m1.update(b'56')
>>> m1.hexdigest()
'e10adc3949ba59abbe56e057f20f883e'

import hashlib
import sys

def check_md5(fname):
    m = hashlib.md5()

    with open(fname, 'rb') as fobj:
        while 1:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)


    return m.hexdigest()



if __name__ == '__main__':
    print(check_md5(sys.argv[1]))

例子:备份

# (nsd1907) [root@room9pc01 day03]# mkdir -p  /tmp/demo/security
# (nsd1907) [root@room9pc01 day03]# mkdir -p  /tmp/demo/backup
# (nsd1907) [root@room9pc01 day03]#  cp  -r /etc/security  /tmp/demo/


from time import strftime
import os
import tarfile
import hashlib
import sys
import pickle

def check_md5(fname):
    m = hashlib.md5()

    with open(fname, 'rb') as fobj:
        while 1:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)


    return m.hexdigest()

def full_backup(src,dst,md5file):
    '源目录打包,计算每个文件的md5值'
    #拼接出打包的文件名
    fname = '%s_full_%s.tar.gz'  % \
            (os.path.basename(src),strftime('%Y%m%d'))
    fname = os.path.join(dst,fname)

    #压缩
    tar =  tarfile.open(fname,'w:gz')
    tar.add(src)
    tar.close()

    #计算每个文件的md5值
    md5dict = {}
    for path, folders, files in os.walk(src):
        for file in files :
            key = os.path.join(path,file)
            md5dict[key] = check_md5(key)

    #把md5字典存到文件中
    with open(md5file,'wb') as fobj:
        pickle.dump(md5dict,fobj)


def incr_backup(src,dst,md5file):
    '找到新增文件和改动的文件,将它们打包: 更新md5值'
    #拼接出打包的文件名
    fname = '%s_back_%s.tar.gz'  % \
            (os.path.basename(src),strftime('%Y%m%d'))
    fname = os.path.join(dst,fname)

    #计算每个文件的md5值
    md5dict = {}
    for path, folders, files in os.walk(src):
        for file in files :
            key = os.path.join(path,file)
            md5dict[key] = check_md5(key)

    #取出前一天的md5值
    with open(md5file,'rb') as fobj:
        old_md5 = pickle.load(fobj)

    #将新增文件和变化文件打包
    tar = tarfile.open(fname,'w:gz')
    for key in md5dict:
        if old_md5.get(key) != md5dict[key]:
            tar.add(key)
    tar.close()

    #更新md5文件
    with open(md5file,'wb') as fobj:
        pickle.dump(md5dict,fobj)

if __name__ == '__main__':
    src = '/tmp/demo/security'
    dst = '/tmp/demo/backup'
    # 周一完全备份,其他时间增量备份
    md5file = '/tmp/demo/md5.data'
    if strftime('%a') == 'Mon':
        full_backup(src,dst,md5file)
    else:
        incr_backup(src,dst,md5file)


######每次增量备份完之后,可以用以下命令查看md5是否有更新
(nsd1907) [root@room9pc01 day03]# strings /tmp/demo/md5.data | grep host
/tmp/demo/security/hostsq

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1046665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一键生成,轻松制作个性化瓜分红包活动二维码

在如今竞争激烈的市场中&#xff0c;营销活动成为各个品牌推广的重要手段。而在朋友圈这个信息交流的平台上&#xff0c;如何引起用户的关注和参与&#xff0c;成为了每个营销人员的关注焦点。而打造一个引爆朋友圈的瓜分红包活动&#xff0c;无疑是一种非常有效的方法。接下来…

Win10系统怎么把桌面路径改为其他盘?

Win10系统怎么把桌面路径改为其他盘&#xff1f;Win10系统默认将桌面文件夹路径设置在系统安装盘中&#xff0c;通常是C盘。但是&#xff0c;如果Win10电脑C盘空间不足了&#xff0c;就会影响系统的正常运行。下面小编给大家介绍在Win10系统中将桌面路径改为其他盘的详细方法。…

代码随想录算法训练营第四十一天 | 动态规划 part 3 | 343. 整数拆分、96.不同的二叉搜索树

目录 343. 整数拆分思路代码 96.不同的二叉搜索树思路代码 343. 整数拆分 Leetcode 思路 dp[i] 表示 分拆数字i&#xff0c;可以得到的最大乘积为dp[i]。dp[i] max(dp[i], max((i - j) * j, dp[i - j] * j)) 贪心解法 这里粘贴一下美版 StefanPochmann 老哥的 idea&#…

Host掌控SSD内黑匣子的历史演进

在固态硬盘&#xff08;SSD&#xff09;的世界里&#xff0c;一直有一个神秘的“黑盒子”现象。这个现象指的是主机&#xff08;Host&#xff09;对SSD的控制能力有限&#xff0c;只能通过既定的接口进行基本的读写操作。但随着技术的不断发展&#xff0c;这个“黑盒子”正在被…

Day-01 从 0 开始搭建一套规范的 Vue3.x 项目工程环境

一、架构搭建 请确保你的电脑上成功安装 Node.js&#xff0c;本项目使用 Vite 构建工具&#xff01; 查看 Node.js 版本&#xff1a; ps&#xff1a; 需要注意的是vite需要你的node的版本在12以上 node -v // v16.20.1 建议将 Node.js 升级到最新的稳定版本&#xff1a;…

基于Laravel 5.6的运动健身类小程序前后端源码

基于Laravel 5.6的运动健身、健康类小程序前后端源码&#xff0c;一套比较基础的运动健康、健身类小程序源码。朋友自己无聊写的&#xff0c;比较基础&#xff0c;有需要的可以拿去修修改改升级开发一下。 使用宝塔安装&#xff0c;比较省事&#xff0c;PHP相关的扩展需要启用…

车载高速CAN(HighSpeed CAN)通信之CAN Bus Off

本文主要以普及CAN通信基本原理为目的&#xff0c;如有从事相关领域或者有意从事车载嵌入式开发的读友们欢迎留言探讨。 本文含有关键字如下。 CAN Bus Off&#xff0c;Bus Off DTC&#xff0c;Bus Off Recovery CAN Bus Off 连接到CAN网络的通信设备一般称为节点&#xff…

信息安全:恶意代码防范技术原理.

信息安全&#xff1a;恶意代码防范技术原理. 恶意代码的英文是 Malicious Code, 它是一种违背目标系统安全策略的程序代码&#xff0c;会造成目标系统信息泄露、资源滥用&#xff0c;破坏系统的完整性及可用性。 目录&#xff1a; 恶意代码概述&#xff1a; &#xff08;1&a…

mac openssl 版本到底怎么回事 已解决

在mac 安装node多版本的时候&#xff0c;有可能把原有的 openssl1.1 版本 直接要再一次升级了&#xff0c;无奈的 php环境 编译器是 openssl 1.1 还是 3.0 &#xff0c;今天来个底朝天的找问题。 brew search openssl 有安装 三个版本。 但是错误提示 是第二个版本。 brew …

知识分享 钡铼网关功能介绍:使用SSLTLS 加密,保证MQTT通信安全

背景 为了使不同的设备或系统能够相互通信&#xff0c;让旧有系统和新的系统可以集成&#xff0c;通信更加灵活和可靠。以及将数据从不同的来源收集并传输到不同的目的地&#xff0c;实现数据的集中管理和分发。 通信网关完美克服了这一难题&#xff0c;485或者网口的设备能通过…

在 Esp32 摄像头上实现边缘脉冲 FOMO 物体检测

轻松在 Esp32 相机上运行边缘脉冲 FOMO 物体检测的世界最佳指南。即使您是初学者 介绍 对象检测是检测图像内感兴趣的对象的任务。直到几年前,由于模型的复杂性和要执行的数学运算的数量惊人,这项任务还需要强大的计算机来完成。 然而,由于像Edge Impulse这样的平台,初学者…

css中常用单位辨析

辨析 px&#xff1a;像素&#xff1b;css中最普遍最常用的单位&#xff0c;不管在何种设备或分辨率上&#xff0c;1px始终代表屏幕上的一个像素。 %&#xff1a;百分比&#xff1b;基于父元素相对属性的百分比。 em&#xff1a;当前字体大小的倍数&#xff1b;基于父元素字体…

HCQ1-1300-D【高速输入】

1高速计数器&#xff1a; 用于记录电机轴位置【编码器信号采集】 2硬件引脚&#xff1a; 总共4个引脚&#xff1a;【A】 ab接编码器信号&#xff0c;或者接近开关信号&#xff08;需要设置计数器工作模式&#xff09; 【B】 【Z】就是编码器Z相&#xff0c;转一圈输出1个脉冲…

04-Zookeeper集群详解

上一篇&#xff1a;03-Zookeeper客户端使用 Zookeeper 集群模式一共有三种类型的角色 Leader: 处理所有的事务请求&#xff08;写请求&#xff09;&#xff0c;可以处理读请求&#xff0c;集群中只能有一个LeaderFollower&#xff1a;只能处理读请求&#xff0c;同时作为 Le…

MACOS系统Qt配置MySQL

1.打开Qt Maintenance Tool必须下载Sources 2.下载后打开/Users/liwanyu/Qt/5.15.2/Src/qtbase/src/plugins/sqldrivers/mysql/mysql.pro直接点开 3. 点开mysql.pro文件&#xff0c;注释第六行 QMAKE_USE mysql 添加三行路径&#xff1a;找到自己的mysql路径和自己的Qt下的 s…

C/C++笔试错题集+图解知识点(一)—— 持续更新中

1. printf("%5.2s", ) #include <iostream> using namespace std; int main() {printf("%s\n", "string");printf("%5.3s\n", "string"); //总共打印五个字符&#xff0c;取"string"的前三个字符&#…

B+树的定义以及查找

1.B树的定义 一棵m阶的B树需满足下列条件: 每个分支结点最多有m棵子树(孩子结点)。非叶根结点至少有两棵子树&#xff0c;其他每个分支结点至少有「m/2]棵子树。结点的子树个数与关键字个数相等。所有叶结点包含全部关键字及指向相应记录的指针&#xff0c;叶结点中将关键字按…

电子电子架构——AUTOSAR信息安全机制有哪些?(上)

电子电子架构——AUTOSAR信息安全机制有哪些&#xff08;上&#xff09; 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 人们会在生活中不断攻击你。他们的主要…

LINUX|ubuntu常用指令

文章目录 查看IP显示当前路径下所有文件安装编译工具GCC、调试工具GDB、连接工具SSHmkdir 创建目录export命令显示当前系统定义的所有环境变量echo $PATH命令输出当前的PATH环境变量的值当前命令行添加环境变量&#xff0c;关闭失效&#xff0c;防止多版本库冲突时使用sudo su打…

零基础学习ESP8266

文章目录 零基础学习ESP8266前言选择硬件如何学习专栏大纲基础部分提高部分 总结 零基础学习ESP8266 前言 最近在空余的时候有用乐鑫的模组&#xff0c;感觉很不错&#xff0c;也决定简单写写。 相信看这篇文章的同学&#xff0c;希望可以熟悉ESP8266这个硬件平台。当然我们…