python “名称空间和作用域” 以及 “模块的导入和使用”

七、名称空间和作用域

可以简单理解为存放变量名和变量值之间绑定关系的地方。

1、名称空间

在 Python 中有各种各样的名称空间:

  • 全局名称空间:每个程序的主要部分定义了全局的变量名和变量值的对应关系,这样就叫做全局名称空间

  • 局部名称空间:在函数的运行中定义的临时的空间叫做局部名称空间,只可以被这个函数所有。函数运行结束后,这个局部的名称空间就会销毁。

  • 内置名称空间:内置名称空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

1、三种名称空间之间的加载顺序
python3 test.py
​
# 1、python解释器先启动,因而首先加载的是:内置名称空间
# 2、执行test.py文件,然后以文件为基础,加载全局名称空间
# 3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
2、名字的查找顺序

当我们要使用一个变量时,先从哪里找?

局部使用:局部名称空间——>全局名称空间——>内置名称空间

x = 1
def f1():
    x = 10
    print(x)
​
f1()  # 输出 10

全局使用:全局——>内置

#需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例
​
x = 1
def f1():
    x = 10
    print(x)
​
print(x)  # 输出  1

2、作用域

作用域就是变量名的生效范围

分为: 全局作用域 和 局部作用域

1、全局作用域

内置的名称空间中的名字和全局名称空间的名字属于这个全局作用域。

  • 全局作用域中的名字,在整个文件的任意位置都能被引用,全局存活,全局内都有效。

2、局部作用域

局部名称空间的名字属于局部作用域。

  • 局部作用域中的名字只能在其本地局部生效和使用。

  • python 中局部作用域就是函数内定义或生成的名字,临时存活,随着函数调用的结束而消失。

八、模块的导入和使用

1、模块介绍

  • Python 有时候称为胶水语言,就是因为它有强大的可扩展性,这个扩展性就是用模块实现的。

  • 模块其实就是一个以 .py 结尾的 Python 文件,这个文件中可以包含变量、函数、类等。

  • 模块可以包含实现了一个或者多个功能的代码。

  • 模块可以在其他 Python 文件中使用,可以通过网络进行传播。

这样的话,如果想在你的程序中实现某些功能,其实网络的其他程序猿已经给你写好了,下载下来,安装到自己的环境下,就可以使用了。

2、为什么要模块化

模块化编程是指将大型,笨拙的编程任务分解为单独的,更小的,更易于管理的子任务或模块的过程。然后可以像构建块一样拼凑单个模块以创建更大的应用程序。

在大型应用程序中模块化代码有几个优点:

  • 简单性:模块通常只关注问题的一小部分,而不是关注当前的整个问题。如果您正在处理单个模块,那么您的头脑中要思考的将有一个较小的问题范围。这使得开发更容易,更不容易出错。

  • 可维护性:模块通常设计为能够在不同的问题域之间实施逻辑边界。如果以最小化相互依赖性的方式编写模块,则对单个模块的修改将对程序的其他部分产生影响的可能性降低。(您甚至可以在不了解该模块之外的应用程序的情况下对模块进行更改。)这使得许多程序员团队在大型应用程序上协同工作更加可行。

  • 可重用性:单个模块中定义的功能可以通过应用程序的其他部分轻松地重用。这消除了重新创建重复代码的需要。

  • 范围:模块通常定义一个单独的命名空间,这有助于避免程序的不同区域中的变量名之间的冲突。

函数模块都是Python中用于促进代码模块化的构造。

3、模块的分类

1、实现方式分类

实际上有两种不同的方法可以在Python中定义模块

  1. 模块可以用Python本身编写。

  2. 模块可以用C编写并在运行时动态加载,就像re正则表达式)模块一样。

以上两种情况下,模块的内容都以相同的方式访问:使用import语句

2、模块的归属分类
    1. 包含在解释中的一个内置的模块本,像[itertools](https://realpython.com/python-itertools/)模块。

    1. 其他机构或个人开发者编写的模块,成为第三方模块

    1. 自己写的 .py 文件,就是自定义的模块

3、第三方模块

从网络上下载的模块称为 第三方模块

安装方法
1、 pip3 工具安装

例如下面的示例是安装用于执行远程主机命令的模块 paramiko

注意: pip3 是 bash 环境下的命令
pip3 install paramiko

python2.x 使用 pip python3.x 使用 pip3 当然这也不是固定的,比如你给 pip3 定义了一个别名 pip

2、源码安装

源码安装就是,从网络上下载没有封装的 python 文件的源码,之后在本地执行其源码中的 setup.py 文件进行安装。

模块的源码一般都有一个主目录,主目录中包含了一个到多个子目录和文件。 但是主目录下一定有一个 setup.py 的文件,这个是源码安装的入口文件,就是需要执行这个文件并且传入一个  install 参数进行源码安装。

示例:

a. 下载源码包
wget https://files.pythonhosted.org/packages/4a/1b/9b40393630954b54a4182ca65a9cf80b41803108fcae435ffd6af57af5ae/redis-3.0.1.tar.gz
b. 解压源码包
tar -xf redis-3.0.1.tar.gz
  1. 进入模块源码的主目录,并安装源码包

上面表示安装成功

4、自定义模块

有的情况下,是需要自己编写一些模块的,这种就是自定义模块了。

示例:

some_mod.py
x = 10
​
li = ['shark', 18]
​
def foo():
    return 30
​
class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age
5、内置模块

模块除了 第三方模块, 自定义模块,还有 内置模块

4、模块的使用

  • 使用模块需要先导入模块名。

  • 模块名就是把 .py 去掉后的文件名。比如 some_mod.py 的模块名就是 some_mod

1、导入模块
import  some_mod
2、使用模块中的对象

要想使用模块中的变量名或者函数名等,只需要使用 模块名.变量名 的方式即可。

例如,下面是使用的了 some_mod 模块中的 foo 函数。

import  some_mod
​
some_mod.foo()
3、更多模块导入的方式

a.  从模块中导入其中的一个对象

from some_mod  import  x

b. 从模块中导入多个对象

from some_mod import x, foo

c. 从模块中导入全部的对象, 不建议这么做

from some_mod import *
4、导入模块时模块的代码会自动被执行一次
st = """www.qfecu.com
千峰欢迎您!
www.qfecu.com
千峰欢迎您!
"""
​
print(st)

5、模块名的搜索路径

当你导入模块或者包的时候, 查找模块或包的顺序:

  1. 系统会先从当前目录下查找

  2. 之后再从sys.path 输出的值中的路径里查找模块名或者包名。

import sys
​
print(sys.path)

sys.path 输出的值是一个 Python 的列表,这个列表我们可以对其修改的。

比如我们可以把某个文件的路径添加到此列表中,通常会这么做。

run.py
import os
import sys
​
BASE_DIR = os.path.dirname(os.path.abspath(__file__))   # python2 
sys.path.insert(0, BASE_DIR)
​
sys.path.insert(0,'D:\gitlab')  # 将D:\gitlab 添加到python解释器的查询列表中
print(sys.path)

九、常用模块

1、sys 模块

提供了一系列有关Python运行环境的变量和函数

#python3 sys模块
#sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,
#用于操控python运行时的环境。
​
!# sys.argv 接收命令行参数,生成一个List,第一个元素是程序本身路径
# sys.modules.keys() 返回所有已经导入的模块列表
# sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
!# sys.exit(n) 退出程序,正常退出时exit(0)
# sys.hexversion 获取Python解释程序的版本值,16进制格式如:0x020403F0
# sys.version 获取Python解释程序的版本信息
# sys.maxsize 获取内存中最大的Int值 python2中是maxint
# sys.maxunicode 获取内存从中最大的Unicode值
# sys.modules 返回系统导入的模块字典,key是模块名,value是模块
!# sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
!# sys.platform 返回操作系统平台名称
# sys.stdout 标准输出
# sys.stdin 标准输入
# sys.stderr 错误输出
!# sys.exec_prefix 返回平台独立的python文件安装的位置
# sys.byteorder 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
# sys.copyright 记录python版权相关的东西
# sys.api_version 解释器的C的API版本
​
import sys
sys.argv         # 命令行参数列表,第一个元素是程序本身路径;用于接收执行
                 # Python 脚本时传的参数
# 示例:
python3 echo.py  
a b c
​
# echo.py 文件内容
import sys
print(sys.argv[1:])
​
# 输出结果
['a', 'b', 'c']
​
print('脚本名称:{}'.format(sys.argv[0]))
for i in sys.argv:
     if i == sys.argv[0]:
         continue
     print('参数为:',i)
                                                                    
print('总参数个数:{}'.format(len(sys.argv)-1)
      
[root@python python]# ./sysargv.py s1 s2 s3 s4 s5
脚本名称:./sysargv.py
参数为: s1
参数为: s2
参数为: s3
参数为: s4
参数为: s5
总参数个数:5

2、os 模块

os模块是与操作系统交互的一个接口,包含普遍的操作系统功能,如果你希望你的程序能够与平台有关的话,这个模块是尤为重要的。

import os
​
# os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径  # pwd
# os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd  # cd 
# os.curdir  返回当前目录: ('.')
# os.pardir  获取当前目录的父目录字符串名:('..')
# os.makedirs('dirname1/dirname2')    可生成多层递归目录 # mkdir -p
# os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 rmdir -p
# os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname  # mkdir
# os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname # rmdir
# os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印  # ls -A
# os.remove()  删除一个文件 # rm -f
# os.rename("oldname","newname")  重命名文件/目录 rename mv
# os.stat('path/filename')  获取文件/目录信息
# os.sep    输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
# os.linesep    输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
# os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
# os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
# os.system("bash command")  运行shell命令,直接显示 #一般用于脚本中去打印 # 这种方法实用性不如 os.popen subprocess.getoutput
# os.environ  获取系统环境变量
# os.path.abspath(path)  返回path规范化的绝对路径
# os.path.split(path)  将path分割成目录和文件名二元组返回   # 不去检测文件系统
# os.path.dirname(path)  返回path的上一层目录。其实就是os.path.split(path)的第一个元素
# os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
# os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False # if [ -e ]
# os.path.isabs(path)  如果path是绝对路径,返回True
# os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False    # if [ -f ]
# os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False    # if [ -d ]
# os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,最后一个绝对路径之前的参数将被忽略
# os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
# os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
​
开始练习
import os
# 获取当前工作目录,即当前python脚本工作的目录路径
os.getcwd()
​
# 切换当前脚本工作目录;相当于shell下cd
os.chdir("./dirname")
​
# 创建单级目录,相当于 shell 中的 mkdir dirname
os.mkdir('dirname')
​
# 递归创建目录
os.makedirs('dir1/dir2')
​
# 删除单级空目录,若目录非空则无法删除,并报错。
os.rmdir('dirname') 
​
# 递归删除 空 目录
os.removedirs('dir1/dir2')  
​
# 列出指定目录下的所有文件和目录,包括隐藏文件,并以列表方式打印
os.listdir('dirname')
​
# 递归查找目录下的文件和目录,返回一个生成器对象。
# 生成器对象是个可迭代对象,每一层包含了三个值:
# 1. 当前目录路径,2. 其下面的所有子目录, 3. 其下面的所有文件
os.walk('dirname')
​
### 练习需求 ###
1.  在 /tmp 目录下,创建目录  a/b/c
2.  进入到 /tmp/a/b 目录下,创建一个目录 f
3.  把当前的工作目录写到 f 目录下的 work.txt 文件内。
4.  删除目录 c
5.  把 /tmp 目录下及其子目录下的所有文件和目录打印到屏幕上
# 如果path存在,返回True;如果path不存在,返回False 在这里值得注意的是,
# 在Linux shell 中,Python会认为: / 左边一定是一个目录,而不是文件
os.path.exists(path) 
​
# 如果path是一个存在的目录,则返回True。否则返回False
os.path.isdir(path)
​
# 如果path是一个存在的文件,返回True。否则返回False
os.path.isfile(path)
​
# 删除一个文件
os.remove('file')
​
# 重命名文件/目录
os.rename("oldname", "new")
​
# 如果path是绝对路径,返回 True
os.path.isabs(path)
​
# 将 path 分割成目录和文件名二元组返回
os.path.split(path)
​
​
# 返回 文件 或 path 规范化的绝对路径
os.path.abspath(path)
​
# 返回path的目录。 其实返回的就是 os.path.split(path) 的第一个元素
os.path.dirname(path)
    
# 将多个路径组合后返回,每个路径之间不需要加路径分隔符(\或者/)    
os.path.join(path1[, path2[, ...]])

3、time 时间模块

1、time 模块

在Python中,通常有这几种方式来表示时间:

  • 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始到目前的秒数。我们运行 type(time.time()),返回的是float类型。

  • 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,周几,一年中第几天,夏令时)

属性                            值
tm_year(年)                  比如2011 
tm_mon(月)                   1 - 12
tm_mday(日)                  1 - 31
tm_hour(时)                  0 - 23
tm_min(分)                   0 - 59
tm_sec(秒)                   0 - 61(60和61为闰秒)
tm_wday(weekday)             0 - 6(0表示周一)
tm_yday(一年中的第几天)        1 - 366
tm_isdst(是否是夏令时)        默认为 0
  • 格式化的时间字符串(Format String)

# 快速认识它们
In [139]: import time
​
In [140]: time.time()
Out[140]: 1522057206.0065496
​
In [141]: time.localtime()     # 本地时间, 结构化时间
Out[141]: time.struct_time(tm_year=2018, tm_mon=3, tm_mday=26, tm_hour=17, tm_min=40, tm_sec=53, tm_wday=0, tm_yday=85, tm_isdst=0)
​
In [142]: time.gmtime()        # 格林威治时间(UTC)
Out[142]: time.struct_time(tm_year=2018, tm_mon=3, tm_mday=26, tm_hour=9, tm_min=43, tm_sec=31, tm_wday=0, tm_yday=85, tm_isdst=0)
​
In [143]: time.strftime("%Y-%m-%d %X")
Out[143]: '2018-03-26 17:40:40'
​
​
#time模块没有time.py文件,是内置到解释器中的模块
#三种时间表示方式
'''
1、时间戳(timestamp): 通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。
2、格式化的时间字符串:"2018-09-03 10:02:01"
3、元组(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
'''
#UTC:(Coordinated Universal Time,世界协调时),亦即格林威治天文时间,世界标准时间。在中国为UTC+8
#DST:(Daylight Saving Time),即夏令时。
​
大家开始练习
import time
#时间戳 time()
print(time.time())
1535939025.4159343
​
#struct_time
localtime([secs]) 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
#当地时间
print(time.localtime(time.time()))
time.struct_time(tm_year=2018, tm_mon=9, tm_mday=3, tm_hour=9, tm_min=46, tm_sec=7, tm_wday=0, tm_yday=246, tm_isdst=0)
print(time.localtime())
time.struct_time(tm_year=2018, tm_mon=9, tm_mday=3, tm_hour=9, tm_min=48, tm_sec=19, tm_wday=0, tm_yday=246, tm_isdst=0)
​
t_local=time.localtime()
print(t_local.tm_year)
print(t_local.tm_mon)
print(t_local.tm_mday)
​
​
#gmtime([secs])  将一个时间戳转换为UTC时区(0时区)的struct_time。
print(time.gmtime())
time.struct_time(tm_year=2018, tm_mon=9, tm_mday=3, tm_hour=1, tm_min=51, tm_sec=38, tm_wday=0, tm_yday=246, tm_isdst=0)
​
mktime(t) : 将一个struct_time转化为时间戳。
print(time.mktime(time.localtime()))
1535939934.0
​
asctime([t]) : 把一个表示时间struct_time表示为这种形式:'Mon Sep  3 10:01:46 2018'。默认将time.localtime()作为参数传入。
print(time.asctime())
Mon Sep  3 10:01:46 2018
​
ctime([secs]) : 把一个时间戳转化为time.asctime()的形式,默认time.time()为参数。
print(time.ctime())
Mon Sep  3 10:05:40 2018
​
strftime(format[, t])
# 把一个代表时间的struct_time转化为格式化的时间字符串。
# 如果t未指定,将传入time.localtime()。
# 如果元组中任何一个元素越界,ValueError的错误将会被抛出。
print(time.strftime("%Y-%m-%d %X"))  #%X 等同于 %H%M%S
print(time.strftime("%Y-%m-%d %X",time.localtime()))
print(time.strftime("%Y-%m-%d %H:%M:%S"))
​
strptime(string[, format])
# 把一个格式化时间字符串转化为struct_time。实际上它是strftime()是逆操作。
print(time.strptime('2018-09-03 10:14:53', '%Y-%m-%d %X'))
time.struct_time(tm_year=2018, tm_mon=9, tm_mday=3, tm_hour=10, tm_min=14, tm_sec=53, tm_wday=0, tm_yday=246, tm_isdst=-1)
​
sleep(secs)
time.sleep(10) #停止10秒,继续运行

格式化时间的变量:

格式含义
%a本地(locale)简化星期名称
%A本地完整星期名称
%b本地简化月份名称
%B本地完整月份名称
%c本地相应的日期和时间表示
%d一个月中的第几天(01 - 31)
%H一天中的第几个小时(24小时制,00 - 23)
%I第几个小时(12小时制,01 - 12)
%j一年中的第几天(001 - 366)
%m月份(01 - 12)
%M分钟数(00 - 59)
%p本地am或者pm的相应符
%S秒(00 - 61)
%U一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。
%w一个星期中的第几天(0 - 6,0是星期天)
%W和%U基本相同,不同的是%W以星期一为一个星期的开始。
%x本地相应日期
%X本地相应时间
%y去掉世纪的年份(00 - 99)
%Y完整的年份
%Z时区的名字(如果不存在为空字符)
%%‘%’字符
2、时间的互相转换

In [153]: time.time()
Out[153]: 1522071229.4780636
    
In [154]: time.localtime(1522071229.4780636)
    
In [155]: time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(1522071229.4780636))
    
In [156]: time.strptime('2018-03-26 21:41', "%Y-%m-%d %H:%M")
    
In [157]: time.mktime(time.localtime())
In [178]: time.ctime(1093849081)
Out[178]: 'Mon Aug 30 14:58:01 2004'
    
In [179]: time.asctime(time.localtime())
Out[179]: 'Mon Mar 26 21:49:41 2018'
    
In [183]: time.strptime('Mon mar 04 21:53:42 2018')
​
In [182]: time.strptime('Mon mar 04 21:53:42 2018', "%a %b %d %H:%M:%S %Y")
time.sleep(5)        # 休眠 5 秒钟
​
print(time.clock())  # 精确到毫秒
3、datetime 模块

datetame 是 time 的升级版

import datetime
In [192]: str(datetime.date.fromtimestamp(time.time()))
Out[192]: '2018-03-26'
​
In [193]: str(datetime.datetime.now())
Out[193]: '2018-03-26 22:09:44.424473'
​
In [194]: datetime.datetime.now() + datetime.timedelta(3)
Out[194]: datetime.datetime(2018, 3, 29, 22, 10, 42, 315584)
​
In [196]: datetime.datetime.now() + datetime.timedelta(minutes=30)
Out[196]: datetime.datetime(2018, 3, 26, 22, 41, 32, 44547)
​
In [15]: datetime.date.strftime(datetime.datetime.now(),'%Y-%m')
Out[15]: '2018-04'
  
In [16]: datetime.datetime.strftime(datetime.datetime.now(),'%Y-%m')
Out[16]: '2018-04'
​
import time,datetime
print('返回当前时间:',datetime.datetime.now())
显示结果:
返回当前时间: 2017-12-19 18:13:01.974500
​
print('时间戳直接转成字符串格式: ',datetime.date.fromtimestamp(time.time()))
显示结果:
时间戳直接转成字符串格式:  2017-12-19
​
print('当前时间精确到微秒:',datetime.datetime.now())
显示结果:
当前时间精确到微妙: 2017-12-19 18:13:01.974500
​
print('当前时间+3天: ',datetime.datetime.now() + datetime.timedelta(3))
显示结果:
当前时间+3天:  2017-12-22 18:13:01.974500
​
print('当前时间-3天',datetime.datetime.now() + datetime.timedelta(-3))
显示结果:
当前时间-3天 2017-12-16 18:13:01.974500
 
print('当前时间+3小时',datetime.datetime.now() + datetime.timedelta(hours=3))
显示结果:
当前时间+3小时 2017-12-19 21:13:01.974500
​
print('当前时间+30分: ',datetime.datetime.now() + datetime.timedelta(minutes=30))
显示结果:
当前时间+30分:  2017-12-19 18:43:01.974500
​
print('当前时间+2年:',datetime.datetime.now()+datetime.timedelta(days=365*2))
显示结果:
当前时间+2年: 2019-12-19 18:13:01.974500
​
c_time = datetime.datetime.now()
print('时间替换:', c_time.replace(minute=3,hour=2)) #时间替换
显示结果:
时间替换: 2017-12-19 02:03:01.974500

4、shutil 压缩打包模块

shutil 是 Python3 中高级的文件 文件夹 压缩包 处理模块

1、拷贝文件

拷贝文件的内容到另一个文件中,参数是文件的相对路径或者绝对路径

import shutil    
shutil.copyfile('./src.file','./dst.file')  #给目标文件命名
2、拷贝文件和权限
import shutil
shutil.copy2('f1.log', 'f2.log')
3、递归拷贝

递归的去拷贝文件夹

shutil.copytree(src, dst, symlinks=False, ignore=None)

shutil.copytree('/home','/tmp/hbak',
                ignore=shutil.ignore_patterns('*.txt'))
# 递归拷贝一个文件夹下的所有内容到另一个目录下,目标目录应该是原来系统中不存在的

shutil.ignore_patterns(*patterns) 忽略某些文件

ignore=shutil.ignore_patterns('排除的文件名', '排除的文件夹名') 支持通配符,假如有多个用逗号隔开

4、递归删除

递归删除一个文件夹下的所有内容

shutil.rmtree('/tmp/hb')
shutil.rmtree('/tmp/hbad/')
​
# 最后结尾的一定是明确的文件名,不可以类似下面这样
shutil.rmtree('/tmp/hbak/*')
5、递归移动

递归的去移动文件,它类似mv命令。

shutil.move('/home/src.file', './shark')
6、压缩

创建压缩包并返回文件路径,例如:zip、tar

# 将 /home/shark 目录下的所以文件打包压缩到当前目录下,
# 名字 shark,格式 gztar。扩展名会自动根据格式自动生成。
​
shutil.make_archive('shark',         # 压缩后文件名
                    'gztar',         # 指定的压缩格式
                    '/home/shark/')  # 被压缩的文件夹名字
​
# 将 /home/shark 目录下的所以文件打包压缩到 /tmp 目录下,名字shark,格式 tar
shutil.make_archive( '/tmp/shark','tar','/home/shark/')
​
# 查看当前 python 环境下支持的压缩格式
ret = shutil.get_archive_formats()
print(ret)
7、解压缩
#                     解压的文件名   解压到哪个路径下,压缩的格式
shutil.unpack_archive('./a/b.tar.gz', './a/c/','gztar')

5、subprocess 模块执行本机系统命令

os.system() 执行的命令只是把命令的结果输出导终端,程序中无法拿到执行命令的结果。

subprocess 是开启一个系统底层的单个进程,执行 shell 命令,可以得到命令的执行结果。

# 在 shell 中运行命令,并且获取到标准正确输出、标准错误输出
In [209]: subprocess.getoutput('ls |grep t')
Out[209]: 'test.py' 
​
In [222]: ret = subprocess.getstatusoutput('date -u')
​
In [223]: ret
Out[223]: (0, '2018年 03月 26日 星期一 14:46:42 UTC')

6、Python3 正则模块(标准库)

1、常用特殊字符匹配内容

字符匹配:

正则特殊字符匹配内容
.匹配除换行符(\n)以外的单个任意字符
\w匹配单个字母、数字、汉字或下划线
\s匹配单个任意的空白符
\d匹配单个数字
\b匹配单词的开始或结束
^匹配整个字符串的开头
$匹配整个字符串的结尾

次数匹配:

正则特殊字符匹配内容
*重复前一个字符 0 - n 次
+重复前一个字符 1 - n 次
重复前一个字符 0 - 1 次
{n}重复前一个字符 n 次 a{2}
匹配 aa
{n,}重复前一个字符 n 次或 n 次以上 a{2,}
匹配 aa
aaa
以上
{n, m}重复前一个字符 n 到 m 次之间的任意一个都可以
2、Python 中使用正则的方法
match

只在整个字符串的起始位置进行匹配

示例字符串

string = "isinstance yangge enumerate www.qfedu.com 1997"

示例演示:

import re
In [4]: r = re.match("is\w+", string)
​
In [8]: r.group()  # 获取匹配成功的结果
Out[8]: 'isinstance'
search

从整个字符串的开头找到最后,当第一个匹配成功后,就不再继续匹配。

In [9]: r = re.search("a\w+", string)
​
In [10]: r.group()
Out[10]: 'ance'
findall

搜索整个字符串,找到所有匹配成功的字符串, 把这些字符串放在一个列表中返回。

In [16]: r = re.findall("a\w+", string)
​
In [17]: r
Out[17]: ['ance', 'angge', 'ate']
sub

把匹配成功的字符串,进行替换。

re.sub的功能
re是regular expression的缩写,表示正则表达式;sub是substitude的缩写,表示替换
re.sub是正则表达式的函数,实现比普通字符串更强大的替换功能 
# 语法:
"""
("a\w+",    "100",        string,     2)
匹配规则,替换成的新内容,  被搜索的对象, 有相同的替换次数
"""
sub(pattern,repl,string,count=0,flag=0)
​
1、pattern正则表达式的字符串 eg中r'\w+'
​
2、repl被替换的内容 eg中'10'
​
3、string正则表达式匹配的内容eg中"xy 15 rt 3e,gep"
​
4、count:由于正则表达式匹配的结果是多个,使用count来限定替换的个数从左向右,默认值是0,替换所有的匹配到的结果eg中2
​
5、flags是匹配模式,可以使用按位或者“|”表示同时生效,也可以在正则表达式字符串中指定
​
eg:
In [24]: import re
In [24]: re.sub(r'\w+','10',"xy 15 rt 3e,gep",2,flags=re.I )
'10 10 rt 3e,gep',
其中r'\w+'为正则表达式,匹配多个英文单词或者数字,'10'为被替换的内容,“xy 15 rt 3e,gep”是re匹配的字符串内容,count只替换前2个,flag表示忽略大小写
​
In [24]: r = re.sub("a\w+", "100", string, 2)
  
In [25]: r
Out[25]: 'isinst100 y100 enumera www.qfedu.com 1997'
​
# 模式不匹配时,返回原来的值
split

以匹配到的字符进行分割,返回分割后的列表

re.split(pattern, string, maxsplit=0, flags=0)
​
pattern compile 生成的正则表达式对象,或者自定义也可
string 要匹配的字符串
maxsplit 指定最大分割次数,不指定将全部分割
​
flags 标志位参数 (了解)
re.I(re.IGNORECASE) 
使匹配对大小写不敏感
​
re.L(re.LOCAL)  
做本地化识别(locale-aware)匹配
​
re.M(re.MULTILINE)  
多行匹配,影响 ^ 和 $
​
re.S(re.DOTALL) 
使 . 匹配包括换行在内的所有字符
​
re.U(re.UNICODE)    
根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
​
re.X(re.VERBOSE)    
该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
In [26]: string
Out[26]: 'isinstance yangge enumerate www.qfedu.com  1997'
​
In [27]: r = re.split("a", string, 1)

使用多个界定符分割字符串

>>> line = 'asdf fjdk; afed, fjek,asdf,  foo'
>>> import re
>>> re.split(r'[;,\s]\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
3、正则分组

从已经成功匹配的内容中,再去把想要的取出来

# match
In [64]: string
Out[64]: 'isinstance yangge enumerate www.qfedu.com  1997'
​
In [65]: r = re.match("is(\w+)", string)
​
In [66]: r.group()
Out[66]: 'isinstance'
​
In [67]: r.groups()
Out[67]: ('instance',)
    
In [68]: r = re.match("is(in)(\w+)", string))
    
In [69]: r.groups()
Out[69]: ('in', 'stance')
​
# search
# 命名分组
In [87]: r = re.search("is\w+\s(?P<name>y\w+e)", string)  
​
In [88]: r.group()
Out[88]: 'isinstance yangge'
​
In [89]: r.groups()
Out[89]: ('yangge',)
6
In [90]: r.groupdict()
Out[90]: {'name': 'yangge'}
8
​
# findall
In [98]: string
Out[98]: 'isinstance all yangge any enumerate www.qfedu.com  1997'
​
In [99]: r = re.findall("a(?P<name>\w+)", string)
​
In [100]: r
Out[100]: ['nce', 'll', 'ngge', 'ny', 'te']
​
In [101]: r = re.findall("a(\w+)", string)
​
In [102]: r
Out[102]: ['nce', 'll', 'ngge', 'ny', 'te']
​
    
# split
In [113]: string
Out[113]: 'isinstance all yangge any enumerate www.qfedu.com 1997'
​
In [114]: r = re.split("(any)", string)
​
In [115]: r
Out[115]: ['isinstance all yangge ', 'any', ' enumerate www.qfedu.com 1997']
​
In [116]: r = re.split("(a(ny))", string)
​
In [117]: r
Out[117]:
['isinstance all yangge ',
 'any',
 'ny',
 ' enumerate www.qfedu.com 1997']
​
In [118]: tag = 'value="1997/07/01"'
​
In [119]: s = re.sub(r'(value="\d{4})/(\d{2})/(\d{2}")', r'\1-\2-\3', tag)
​
In  [120]: s
Out [120]: value="1997-07-01"
编译正则

对于程序频繁使用的表达式,编译这些表达式会更有效。

compile 函数用于编译正则表达式,返回的是一个正则表达式( Pattern )对象,利用这个对象的相关方法再去匹配字符串。

好处:

re 模块会维护已编译表达式的一个缓存。

不过,这个缓存的大小是有限的,直接使用已编译的表达式可以避免缓存查找开销。

使用已编译表达式的另一个好处是,通过在加载模块时预编译所有表达式,可以把编译工作转到应用 一开始时,而不是当程序响应一个用户动作时才进行编译。

In [130]: regexes = re.compile("y\w+")
​
In [131]: r = regexes.search(string)
​
In [132]: r.group()
Out[132]: 'yangge'
常用正则
# IP:
r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b"
# 手机号:
r'\b1[3|4|5|6|7|8|9][0-9]\d{8}'
# 邮箱:
shark123@qq.com
shark123@163.com
r'[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+'
强调知识点
# 匹配所有包含小数在内的数字
print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']
​
#.*默认为贪婪匹配
print(re.findall('a.*b','a1b22222222b')) 
#['a1b22222222b']
​
#.*?为非贪婪匹配:推荐使用
print(re.findall('a.*?b','a1b22222222b')) 
#['a1b']
元字符
# \b 表示匹配单词边界,详见后面的速查表
​
In [17]: re.search('hello\b', 'hello world')
​
In [18]: re.search('hello\\b', 'hello world')
Out[18]: <_sre.SRE_Match object; span=(0, 5), match='hello'>

Python 自己也有转义

使用 r 禁止 Python 转义

In [19]: re.search(r'hello\b', 'hello world')
Out[19]: <_sre.SRE_Match object; span=(0, 5), match='hello'>
扩展知识点

最后一个参数 flag

可选值有:

re.I       # 忽略大小写

示例:

In [186]: s1 = string.capitalize()
​
In [187]: s1
Out[187]: 'Isinstance all yangge any enumerate www.qfedu.com 1997'
​
In [192]: r = re.search('is',s, re.I)
Out[192]: <_sre.SRE_Match object; span=(0, 2), match='Is'>
4、正则模式速查表
模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...]不在[]中的字符:abc 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{n,m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b匹配a或b
(re)匹配括号内的表达式,也表示一个组
\w匹配字母数字及下划线
\W匹配非字母数字及下划线
\s匹配任意空白字符,等价于 [\t\n\r\f].
\S匹配任意非空字符
\d匹配任意数字,等价于 [0-9].
\D匹配任意非数字
\A匹配字符串开始
\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z匹配字符串结束
\G匹配最后匹配完成的位置。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等.匹配一个换行符。匹配一个制表符。等
\1...\9匹配第n个分组的内容。
\10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

7、Python3 邮件模块

使用第三方库 **yagmail**


更新: 第三种方式的隐藏用户名和密码的方式,目前不再支持


1、简单介绍 yagmail

目标是尽可能简单,无痛地发送电子邮件。

最终的代码如下:

import yagmail
yag = yagmail.SMTP()
contents = ['This is the body, and here is just text http://somedomain/image.png',
            'You can find an audio file attached.', '/local/path/song.mp3']
yag.send('to@someone.com', '邮件标题', contents)

或者在一行中实现:

yagmail.SMTP('mygmailusername').send('to@someone.com', 'subject', 'This is the body')

当然, 以上操作需要从你自己系统的密钥环中读取你的邮箱账户和对应的密码。关于密钥环稍后会提到如何实现。

2、安装模块
pip3 install  yagmail    # linux / Mac
pip install   yagmail    # windows

这样会安装最新的版本,并且会支持所有最新功能,主要是支持从密钥环中获取到邮箱的账户和密码。

3、关于账户和密码

开通自己邮箱的 **SMTP**** 功能,并获取到授权码**

这个账户是你要使用此邮箱发送邮件的账户,密码不是平时登录邮箱的密码,而是开通 POP3/SMTP 功能后设置的客户端授权密码。

这里以 126 邮箱为例:

4、方式一:不使用系统的密钥环

不使用系统的密钥环,可以直接暴露账户和密码在脚本里

import yagmail
yag = yagmail.SMTP(
            user='自己的账号',
            password='账号的授权码',
            host='smtp.qq.com',  # 邮局的 smtp 地址
            port='端口号',       # 邮局的 smtp 端口
            smtp_ssl=False)
​
yag.send(to='收件箱账号',
         subject='邮件主题',
         contents='邮件内容')
5、方式二: 使用系统的密钥环管理账户和授权码

模块支持从当前系统环境中的密钥环中获取账户和密码,要想实现这个功能,需要依赖模块 keyring。之后把账户和密码注册到系统的密钥环中即可实现。

1. 安装依赖模块

pip3 install  keyring 
​
# CentOS7.3 还需要安装下面的模块
pip3 install keyrings.alt

2. 开始向密钥环注册

import yagmail
yagmail.register('你的账号', '你的授权密码')

注册账户和密码,只需要执行一次即可。

3. 发送邮件

import yagmail
​
yag = yagmail.SMTP('自己的账号',
            host='smtp.qq.com',  # 邮局的 smtp 地址
            port='端口号',       # 邮局的 smtp 端口
            smtp_ssl=False  # 不使用加密传输
)
​
yag.send(
    to='收件箱账号',
    subject='邮件主题',
    contents='邮件内容')
6、示例展示

下面是以我的 126 邮箱为例, 使用系统密钥环的方式,向我的 163邮箱发送了一封邮件。

import yagmail
​
yag = yagmail.SMTP(user='shark@126.com',
                   host='smtp.126.com',
                   port=25,
                   smtp_ssl=False)
yag.send(to='docker@163.com',
         subject='from shark',
         contents='test')

这样就愉快的发送了一封测试邮件到 docker@163.com 的邮箱。

当然前提是:

  1. 126 邮箱开通了 SMTP功能。

  2. 把 126 邮箱的账号和密码已经注册到自己系统的密钥环中。

7、发送附件

发送

发送附件只需要给 send方法传递 attachments 关键字参数

比如我在系统的某一个目录下有一张图片,需要发送给 docker@163.com

import yagmail
​
yag = yagmail.SMTP(user='shark@126.com',
                   host='smtp.126.com',
                   port=25,
                   smtp_ssl=False)
yag.send(to='docker@163.com',
         subject='from shark',
         contents='test',
         attachments='./松鼠.jpeg')
8、收到的邮件和附件

image.png

9、使用 ssl 发送加密邮件

要发送加密邮件,只需要把 smtp_ssl 关键字参数去掉即可,因为默认就是采用的加密方式 smtp_ssl=True

不传递 stmp_ssl 关键字参数的同时,需要设置端口为邮箱服务提供商的加密端口,这里还是以 126 邮箱为例,端口是 465

import yagmail
​
yag = yagmail.SMTP(user='shark@126.com',
                   host='smtp.126.com',
                   port=465)
yag.send(to='docker@163.com',
         subject='from sharkyunops',
         contents='test',
         attachments='./松鼠.jpeg')
10、发送 带 html 标记语言的邮件内容

在实际的生产环境中,经常会发送邮件沟通相关事宜,往往会有表格之类的内容,但是又不想以附件的形式发送,就可以利用 html 标记语言的方式组织数据。

import yagmail
​
yag = yagmail.SMTP(user='shark@126.com',
                   host='smtp.126.com',
                   port=465)
​
html="""<table border="1">
    <thead>
    <tr>
        <th>姓名</th>
        <th>年龄</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>shak</td>
        <td>18</td>
    </tr>
    <tr>
        <td>西瓜甜</td>
        <td>28</td>
    </tr>
    </tbody>
</table>
"""
​
yag.send(to='docker@163.com',
         subject='from sharkyunops',
         contents=['test',html])

11、更多

如果不指定to参数,则发送给自己

如果to参数是一个列表,则将该邮件发送给列表中的所有用户

attachments 参数的值可以是列表,表示发送多个附件

8、Python3 paramiko 模块

Paramiko 模块提供了基于ssh连接,进行远程登录服务器执行命令和上传下载文件的功能。这是一个第三方的软件包,使用之前需要安装。

1、安装
pip3 install paramiko
2、执行命令
1、基于用户名和密码的连接

封装 Transport

import paramiko 
#实例化一个transport(传输)对象
transport = paramiko.Transport(('172.16.32.129',2323))
#建立连接
transport.connect(username='root',password='123')
#建立ssh对象
ssh = paramiko.SSHClient()
#绑定transport到ssh对象
ssh._transport=transport
#执行命令
stdin,stdout,stderr=ssh.exec_command('df')
#打印输出
print(stdout.read().decode())
#关闭连接
transport.close()
​
import paramiko
transport = paramiko.Transport(('172.16.153.134', 22))
transport.connect(username='root', password='upsa')
​
ssh = paramiko.SSHClient()
ssh._transport = transport
​
stdin, stdout, stderr = ssh.exec_command('df -P')
print(stdout.read().decode())
​
transport.close()
3、文件上传下载

SFTPClient:

用于连接远程服务器并进行上传下载功能。

下面的命令可以快速创建密钥对,并用 -t 指定了算法类型为 ecdsa

ssh-keygen -t ecdsa -N "" ssh-keygen ssh-copy-id 192.168.95.154

1、基于用户名密码上传下载
import paramiko
transport = paramiko.Transport(('10.18.46.104',22))
transport.connect(username='root',password='123.com')
#paramiko.SSHClient()
sftp = paramiko.SFTPClient.from_transport(transport)
​
# 将ssh-key.py 上传至服务器 /tmp/ssh-key.py
sftp.put('ssh-key.py', '/tmp/ssh-key.txt')  # 后面指定文件名称
​
# 将远程主机的文件 /tmp/ssh-key.py 下载到本地并命名为  ssh-key.txt
sftp.get('/tmp/ssh-key.py', 'ssh-key.txt')
​
transport.close()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0508GoodsContent的Maven项目

0508GoodsContent的Maven项目包-CSDN博客 数据库字段 页面需求

OFDM802.11a的FPGA实现(十五)短训练序列:STS(含Matlab和verilog代码)

原文链接&#xff08;相关文章合集&#xff09;&#xff1a;OFDM 802.11a的xilinx FPGA实现 1.前言 在之前已经完成了data域数据的处理&#xff0c;在构建整个802.11a OFDM数据帧的时候&#xff0c;还剩下前导码和signal域的数据帧&#xff0c;这两部分的内容。 PLCP的前导部分…

八年前端开发之路中遇到的一些实用技巧分享——代码思路及通用场景

在开发中比较有用的代码思路 1. 链式编程2. 高阶函数应用-(添加数据并提供删除方法)3. 利用Promise链切入&#xff08;延迟执行&#xff09;4. 通过中间层来解决问题&#xff08;装饰者模式&#xff09;5. 单例模式 1. 链式编程 所谓链式编程即是函数调用后返回对象本身 let …

LoRA Land: 310个经微调的大语言模型可媲美GPT-4

摘要 低秩自适应 (LoRA) 已成为大语言模型 (LLM) 参数有效微调 (PEFT) 中最广泛采用的方法之一。LoRA 减少了可训练参数的数量和内存使用,同时达到了与全面微调相当的性能。该研究旨在评估在实际应用中训练和服务使用 LoRA 微调的 LLM 的可行性。首先,该研究测量了在 10 个基础…

搞什么副业可以月入过万?

月入过万的副业不是一件容易的事情&#xff0c;它需要你付出很多努力和时间。以下是一些可能能够实现月入过万的副业 1. 自媒体运营 通过开设自己的公众号、博客或YouTube频道&#xff0c;积累一定的粉丝和流量&#xff0c;然后通过广告、赞助、商品销售等方式赚取收入。 2. …

110份财务常用excel模板(个税、采购、报销、预算),超实用!

如果你还在为报表头疼&#xff0c;那你一定不能错过这篇干货满满的分享&#xff01; 个税报表 个人所得税&#xff0c;听起来就头大&#xff1f;别担心&#xff0c;掌握这些技巧&#xff0c;轻松搞定&#xff01; - 记录员工收入&#xff0c;确保数据准确无误 - 计算应纳税…

【Redis7】10大数据类型之Bitfield类型

文章目录 1. Bitfield简介2. BITFIELD key [GET type offset]3. BITFIELD key [SET type offset value]4. BITFIELD key [INCRBY type offset increment] 1. Bitfield简介 Bitfield(位域)命令可以将一个 Redis 字符串看作是一个由二进制位组成的数组&#xff0c; 并对这个数组…

Qwen-VL环境搭建推理测试

引子 这几天阿里的Qwen2.5大模型在大模型圈引起了轰动&#xff0c;号称地表最强中文大模型。前面几篇也写了QWen的微调等&#xff0c;视觉语言模型也写了一篇CogVLM&#xff0c;感兴趣的小伙伴可以移步Qwen1.5微调-CSDN博客。前面也写过一篇智谱AI的视觉大模型&#xff08;Cog…

c++编程(11)——string类的模拟实现

欢迎来到博主的专栏——c编程 博主ID&#xff1a;代码小豪 文章目录 前言string类的模拟实现string的成员对象构造、赋值、析构访问成员对象的接口访问字符串中的元素迭代器对字符序列的插入、删除元素操作mystring类的相关操作 mystring类的所有模拟实现以及测试案例 前言 本…

云服务器和主机的区别

在今天的数字化时代&#xff0c;对于个人和企业来说&#xff0c;选择适当的服务器托管解决方案至关重要。然而&#xff0c;很多人对于云服务器和传统主机之间的区别不太清楚。本文将为您提供一个详细的指南&#xff0c;帮助您理解云服务器与主机之间的区别&#xff0c;以便您能…

光耦 IS314W中文资料 IS314W引脚图及功能说明

IS314W是一款IGBT/MOSFET输出型光耦&#xff0c;由Isocom公司制造。它主要用于驱动用于电机控制和电源系统变频器的功率IGBT和MOSFET。以下是该产品的部分功能和参数&#xff1a; - 两个独立的光耦输出通道 - 轨对轨输出电压 - 最大峰值输出电流&#xff1a;1.0A - 最小峰值输…

一文扫盲(13):电商管理系统的功能模块和设计要点

电商管理系统是一种用于管理和运营电子商务平台的软件系统。它提供了一系列功能模块&#xff0c;帮助企业进行商品管理、订单管理、会员管理、营销推广、数据分析等工作。本文将从以下四个方面介绍电商管理系统。 一、什么是电商管理系统 电商管理系统是一种集成了各种功能模块…

Moveit Noetic的运动规划组python接口

Moveit Noetic的运动规划组python接口 记录学习如何使用moveit的python API进行机械臂的控制 &#x1f680; 环境配置 &#x1f680; ubuntu 20.04ros noeticmoveit noetic法奥机械臂 frcobot_fr5 文章目录 Moveit Noetic的运动规划组python接口1. 设置moveit功能包2. 编写M…

springboot月度员工绩效考核管理系统

摘要 本月度员工绩效考核管理系统采用java语言做为代码编写工具&#xff0c;采用mysql数据库进行系统中信息的存储与处理。框架采用springboot。 本系统的功能分为管理员和员工两个角色&#xff0c;管理员的功能有&#xff1a; &#xff08;1&#xff09;个人中心管理功能&am…

解决OpenHarmony设备开发Device Tools工具的QUICK ACCESS一直为空

今天重新安装了OpenHarmony设备开发的环境&#xff0c;在安装过程中&#xff0c;到了工程之后&#xff0c;QUICK ACCESS一直为空。如下图红色大方框的内容一开始没有。 解决方案&#xff1a; 在此记录我的原因&#xff0c;我的原因主要是deveco device tools的远程连接的是z…

Spring Bean的生命周期 五步 七步 十步 循序渐进

&#x1f468;‍&#x1f3eb; 参考视频地址 &#x1f496; 五步版 实例化 bean&#xff08;构造方法&#xff09;属性注入&#xff08;set() 方法&#xff09;初始化方法&#xff08;自定义&#xff09;使用bean销毁方法&#xff08;自定义&#xff09; &#x1f496; 七步版…

janus源码分析(1)--代码结构整理

基础说明 janus官网 https://janus.conf.meetecho.com/index.html janus源码地址 https://github.com/meetecho/janus-gateway 编译及部署参考 https://pro-hnb.blog.csdn.net/article/details/137730389?spm1001.2014.3001.5502 https://pro-hnb.blog.csdn.net/article/deta…

Online RL + IL : TGRL: An Algorithm for Teacher Guided Reinforcement Learning

ICML 2023 Poster paper Intro 文章设定一个专家策略&#xff0c;给出两种优化目标。一个是基于专家策略正则的累计回报&#xff0c;一个是原始累计回报。通过比较二者动态的衡量专家策略对智能体在线学习的影响程度&#xff0c;进而实现在线引导过程。 Method 原始的RL目标…

MyBatis常见报错:org.apache.ibatis.binding.BindingException

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 异常现象描述 当开发者在使用MyBatis进行数据库操作时&#xff0c;可能会遇到org.apache.ibatis.binding.BindingException: Parameter appId not found这样的错误提示。这个错误通常会让程序无法正常运行&#xff…

DeepSort / Sort 区别

推荐两篇博文,详细介绍了deepsort的流程及代码大致讲解: https://blog.csdn.net/qq_48764574/article/details/138816891 https://zhuanlan.zhihu.com/p/196622890 DeepSort与Sort区别: 1、Sort 算法利用卡尔曼滤波算法预测检测框在下一帧的状态,将该状态与下一帧的检测结…