数据双向链表queue:队列和栈
排序字典:orderrdDict
计数器:counter
什么是模块?
什么是包及如何使用第三方包?
模块使用总结?
自定义函数一般格式;
函数参数中的不可变数据类型和可变数据类型;
变量作用域;
一般格式;
边界条件(值比较和逻辑判断)
多个条件判断
容器,布尔,None,数字,字符串。
容器:列表,元组,集合,字典
管理容器的方法:如何定义容器?容器的四个操作:增删改查
【数据类型】
加号 + 是字符串的连接符, 星号 * 表示复制当前字符串,紧跟的数字为复制的次数;
Python 使用反斜杠()转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串;
Python中的字符串、元组不能改变;
数字型包括int float bool complex(复数)
内置的 type() 函数可以用来查询变量所指的对象类型
当你指定一个值时,Number 对象就会被创建,可以通过使用del语句删除单个或多个对象
数字运算
2/4 ##除法,得到一个浮点数
2//4 ##除法,得到一个整数
2 ** 5 ##乘方
列表[]
list = [‘1234’, 234, 2.3, ‘adc’, [123,‘abc’]]
列表可以完成大多数集合类的数据结构实现;
列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)
和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表
索引值以 0 为开始值,-1 为从末尾的开始位置
print (list * 2) ##输出两次列表
print (list + list) ##连接列表
del list[2] ##删除列表第三个元素
list.append(‘dfg’) ##增加列表元素
元组()
元组写在小括号()内,元素之间用逗号隔开
元组(tuple)与列表类似,不同之处在于元组的元素不能修改
元组与字符串类似,可以被索引且下标索引从0开始,-1 为从末尾开始的位置也可以进行截取
可以把字符串看作一种特殊的元组
集合set()或者{}
创建格式: parame = {value01, value02, …} 或者 set(value)
集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员
基本功能是进行成员关系测试和删除重复元素
可以使用大括号{ }或者set()函数创建集合
备注:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典
stu.add(‘yus’) ##增加元素(一次一个)
stu.update(‘11’, ‘23’) ##增加元素(一次可多个)
stu.discard(‘eee’) ##删除元素,若集合中不存在,则发生错误
stu.pop() ##在交互模式中,pop是删除集合的第一个元素(排序后的集合的第一个元素)
‘Tony’ in stu ##判断元素 Tony 是否在集合stu中,存在则返回true,不存在则返回false
len(stu) ##计算元素个数、 字典 | 列表 | 元素 都适用
注:修改元素为先删除、后添加
e.g.
#!/usr/bin/python3
stu = {‘Tom’, ‘Tony’, ‘Mary’, ‘Jack’, ‘Tony’}
print (stu) ##输出集合,重复的元素被自动去掉
#成员测试
if ‘Tony’ in stu
print (‘Tony at the stu Set’)
else :
print (‘Tony not at the stu Set’)
#set 可以进行集合运算
a = set(‘abcd’)
b = set(‘ace’)
print(a - b) ##a和b的差集 | 并集 & 交集 ^不同时存在的元素(与&互斥)
11. 字典Dictionary 标识用{}
1)在同一个字典中,键(key)必须是唯一的,且可不是同一类型,与索引类似;
e.g. key = ‘one’ | key = 2
2)键(key)必须使用不可变类型;
3)字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合;
4)列表是有序的对象集合,字典是无序的对象集合;
两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取;
5)字典查询用print(),删除元素用del,修改元素直接覆盖,增加用dict[‘age’] = ‘1234’
dict.keys() ##输出所有键
dict.values() ##输出所有值
dict.clear() ##清空字典
del dict ##删除字典
python魔法方法:
1.doc: 描述类信息
2.str: 对象的描述信息
3.module: 表示当前操作的对象在那个模块
4.class: 表示当前操作对象的类是什么
python的%:格式化输出
%[(name)][flags][width].[precision]typecode
(name)为命名
flags: + 右对齐 - 左对齐 ''正数填充一个空格,从而与负数对齐 0 使用0填充
width: 宽度
precision: 小数点后精度
typecode: 数据类型
python函数
func(‘Steve’, ‘Bill’)
func(‘Steve’, ‘Bill’, ‘John’, ‘Amir’)
func(firstname=‘Steve’, lastname=‘Jobs’)
func(lastname=‘Jobs’, firstname=‘Steve’)
func(firstname=‘Bill’, lastname=‘Gates’, age=55)
func(firstname=‘Bill’) # raises KeyError 参数只能多于,不能少于
func()
func(‘Steve’)
输出:
Calling function argument:
Hello World
Calling function argument:
Hello World
__main__
是顶层代码执行的顶层作用域的名称。if __name__
== '__name__'
sys.argv[0] = re.sub(r’(-script.pyw?|.exe)?$', ’ ', sys.argv[0])
sys.exit(ttt())
----------------------------------------------------------------------------
re是regular expression的所写,表示正则表达式
sub是substitute的所写,表示替换
其中三个必选参数:pattern, repl, string
两个可选参数:count, flags
pattern,表示正则中的模式字符串
repl,就是replacement,被替换的字符串
string,即表示要被处理,要被替换的那个string字符串
count,对匹配到的内容,只处理其中一部分
e.g. count为2,则便是只处理前两个数字
flags
-----------------------------------------------------------------------------
在Python中,if __name__
== '__main__'
: 是一个常见的条件语句,
用于判断当前模块是否被直接执行。
当一个Python模块被直接执行时,其__name__
属性的值会被设置为'__main__'
,
而当模块被导入时,__name__
的值则是模块的名称。
因此,通过使用if __name__
== '__main__'
: 条件语句,
可以将一些代码块限制在仅在模块被直接执行时运行,而不是在模块被导入时执行。
这种用法通常用于将模块作为脚本执行时的一些初始化操作,或者用于进行一些测试和调试操作。
这样可以确保模块在被导入时不会执行这些操作,而只有在直接执行时才会执行。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在Python中,r前缀表示一个原始字符串(raw string)。
原始字符串会保留字符串中的所有字符,包括转义字符,不进行任何转义操作。
在正则表达式中,r前缀通常用于标识一个原始字符串,以便保留正则表达式中的特殊字符,
而不进行转义。这样可以使正则表达式更加清晰和易读。
e.g. 在正则表达式中,"."
表示匹配任意字符,而"\."
表示匹配一个点字符。
但是,如果使用原始字符串r'\.'
,则不需要进行转义,直接表示匹配一个点字符。
在这个例子中,r'(-script\.pyw?|\.exe)?$'
中的r前缀表示这是一个原始字符串,
保留了正则表达式中的特殊字符".“和”"的原始含义,而不进行转义。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这三个参数是re.sub()函数的参数,具体含义如下:
r'(-script\.pyw?|\.exe)?$'
:这是一个正则表达式模式,用于匹配需要替换的字符串。''
:这是一个空字符串,用于替换匹配到的字符串。综合起来,这行代码的作用是将sys.argv[0]中以"-script.py"或"-script.pyw"或".exe"结尾的部分
替换为空字符串。也就是将脚本文件名中可能包含的后缀名或命令行参数去除,
得到一个更简洁的文件名。
even_nums = [x for x in range(21) if x%2 == 0] #列表推导式
print(even_nums)
2) 适用于数字列表、也适用于字符串列表、也适用于嵌套循环的列表推导
names = [‘Steve’, ‘Bill’, ‘Ram’, ‘Mohan’, ‘Abdul’]
names2 = [s for s in names if ‘a’ in s]
print(names2) #字符串列表
nums1 = [1, 2, 3]
nums2 = [4, 5, 6]
nums=[(x,y) for x in nums1 for y in nums2]
print(nums) #嵌套循环的列表推导
现象:(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)
nums = [x for x in range(21) if x%20 if x%50]
print(nums)
3) 列表推导的应用之一是将包含多个列表的列表展平为单个列表
matrix=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flatList=[num for row in matrix for num in row]
print(flatList)
现象:[1, 2, 3, 4, 5, 6, 7, 8, 9]
正则表达式是定义搜索模式的字符序列,主要用于在搜索引擎和文本处理器中执行查找和替换操作
Python 通过作为标准库的一部分捆绑的re模块提供正则表达式功能
* . ^ $ + ? [] \ | () {} **
[a-c]
:匹配a,b,c\d
: 匹配任意十进制数字,等价[0-9]\D
: 匹配任意非数字字符\s
: 匹配任意空白字符\S
: 匹配任意非空白字符\w
: 匹配任何字母数字字符\W
: 匹配任何非字母数字字符*
: 匹配前面的字符 0 次或多次.
: 匹配除换行符(\n)以外的任何单个字符^
: 匹配字符串的开头$
: 匹配字符串的结尾+
: 匹配前面的字符 1 次或多次?
: 匹配前面的字符 0 次或 1 次[]
: 匹配括号中的任意一个字符\
: 转义字符,用于匹配特殊字符|
: 或, 匹配符号左右两边的任意一个表达式()
: 分组, 将括号中的表达式作为一个整体进行匹配{}
: 花括号,用于匹配重复次数{n}
匹配前面的字符 n 次{n,}
匹配前面的字符至少 n 次{n,m}
匹配前面的字符至少 n 次,至多 m 次**
: 匹配前一个表达式 0 次或多次,等价于 *\b
: 词与非词的界限例1:
from re import match
mystr = “Welcome to TutorialsTeacher”
obj1 = match(“We”, mystr)
print(obj1)
obj2 = match(“teacher”, mystr)
print(obj2)
输出:
None
备注:span=(0, 2) 表示匹配的结果在原字符串中的起始位置(包含)和结束位置(不包含)
例2:
import re
pattern = “We”
string = “We are the champions”
match = re.search(pattern, string)
if match:
print(match.span()) # 输出 (0, 2)
4) re.search(pattern, str):给定字符串的任意位置搜索指定的模式,并在第一次出现时停止搜索
5) re.findall(pattern, str):给定字符串的任意位置搜索指定的模式,直至搜索完字符串后才停止搜索
6) re.finditer(pattern, str):返回目标字符串中所有匹配项的迭代器对象
7) re.split(pattern, str):等价str对象的 split() 方法
每次发现空白时, 它都会拆分给定的字符串, 并去除列表中的pattern
8) re.compile():取别名, 可以在不同的正则表达式函数中重复使用
from re import *
pattern = compile(r’[aeiou]‘)
string = “Flat is better than nested. Sparse is better than dense.”
words = split(r’ ', string)
for word in words:
print(word, pattern.match(word))
用户线程(User Thread):
总的来说,内核线程由操作系统内核管理和调度,具有更高的开销和更好的并行性能,但线程的创建和切换开销较大;
而用户线程由用户程序库管理和调度,开销较小,但并不能真正并行执行,只能在单个内核线程中轮流执行
在实际应用中,通常会将用户线程映射到内核线程上运行,以充分利用多核处理器的并行性能。这种方式称为"一对一"模型
还有其他线程模型,如"多对一"模型和"多对多"模型,它们的线程管理和调度方式有所不同
2) python多线程的好处:
一个进程中的多个线程共享相同的数据空间,因此可以比单独的进程更容易地共享信息或相互通信。
线程不需要太多内存开销;就内存需求而言,它们比进程便宜。
多线程程序可以在具有多个 CPU 的计算机系统上运行得更快,因为这些线程可以同时执行
lock = threading.Lock() #初始化原语锁
lock.acquire()
lock.release()
获取锁: acquire(blocking=True, timeout=-1)
当它在没有参数的情况下被调用时,它会一直阻塞,直到锁被解锁
该方法可以采用 2 个可选参数,它们是:
阻塞标志
如果该锁已经被某个其他线程获得,则该标志如果作为False发送,将不会阻塞该线程,
并将作为结果返回False。
如果您将该阻塞标志的值提供为True,那么如果其他线程持有锁,调用线程将被阻塞,一旦锁被释放,
那么您的线程将获得锁并返回True。
timeout 参数用于提供一个正浮点值,该值指定如果其他线程正在持有锁,调用线程将被阻塞的秒数。
默认值为 -1 表示如果线程不能立即获得锁,它将被无限期阻塞
释放锁: release()
如果锁被锁定,这个方法会将其重置为解锁状态,然后返回。此外,该方法可以从任何线程调用
2) 可重入锁
同一个线程可以多次获取可重入锁
两个方法: acquire() 和 release()方法
lock = threading.RLock() #初始化可重入锁
lock.acquire()
try:
first = get_first_line()
second = get_second_line()
finally:
lock.release()
return first, second
are_you_coming = threading.Event()
isSet():当且仅当内部标志为真时,此方法返回真
set():当对任何事件对象调用此方法时,内部标志被设置为 true, 唤醒线程
clear():将内部标志重置为 false, 随后对调用clear()的事件调用wait()的线程将阻塞,直到内部标志再次不为真
wait():
让任何线程都等待一个事件时:
在内部标志设置为 false 的事件上调用这个方法,这样做将阻塞线程,直到事件的内部标志为 true
定时器对象是使用Thread类的子类Timer类创建的
使用这个类,我们可以为任何应该在一定时间后运行的操作设置一个延迟(计时器),并且可以在该延迟期间轻松取消
计时器通过调用其start()方法启动,就像普通线程一样;
定时器线程可以通过调用其cancel()方法来停止(在其动作开始之前)
threading.Timer(interval, function, args=[], kwargs={})
创建一个计时器对象,在经过interval秒后,该对象将运行带有参数args和关键字参数kwargs的功能
start():启动计时器对象的执行,当我们调用这个方法时,定时器对象启动它的定时器
cannel():停止计时器并取消计时器对象操作的执行。
这只有在计时器尚未执行其动作的情况下才会起作用,如果计时器已经执行了其动作,则 cancel() 方法将不起作用
在编程中,装饰器是一种设计模式, 它可以动态地向对象添加额外的职责
@mydecorator
def greet():
print (‘Hello!’, end=‘’)
greet()
Hello! How are you?
典型的装饰器函数如下:
def mydecoratorfunction(some_function): # decorator function
def inner_function():
# write code to extend the behavior of some_function()
some_function() # call some_function
# write code to extend the behavior of some_function()
return inner_function # return a wrapper function
----------------------------
3) 内置装饰器
python库包含很多内置装饰器, 作为定义属性、类方法、静态方法等的快捷方式
装饰者 描述
@property 将方法声明为属性的setter或getter方法
@classmethod 将方法声明为类的方法, 可以使用类名调用该方法
@staticmethod 将方法声明为静态方法(使用类名而不是实例来调用静态方法)
因此,通过类名调用普通方法时,实际上是在类的命名空间中直接调用该方法,而不需要创建实例。这样的调用方式通常用于执行与类和实例无关的功能,例如工具函数或类级别的操作。
总结起来,通过类名调用普通方法和类方法的区别在于:
通过类名调用普通方法时,不会创建实例,可以执行与类和实例无关的功能。
通过类名调用类方法时,不会创建实例,但可以执行与类相关的操作,并可以访问和修改类的属性。
通过实例调用普通方法和类方法时,会创建实例,并可以访问和修改实例的属性。
class Itclaas:
def name_func():
print (‘hello’)
Itclaas.name_func()
那为什么这个可以, 普通方法只能通过实例调用吧!
这个例子可以成功调用name_func()是因为name_func()没有定义任何参数,因此不需要传入实例作为参数。
在这种情况下,即使通过类名来调用普通方法,也不会导致参数不匹配的错误。
然而,需要注意的是,虽然这个例子可以成功运行,但这并不是一种常见的用法。
通常情况下,普通方法的第一个参数应该是实例本身,以便在方法内部可以访问和操作实例的属性。
因此,建议在实际开发中,按照约定的方式使用普通方法和类方法,以提高代码的可读性和可维护性。
===================================================
模块加载步骤:
先在 /usr/bin/文件下各种驱动,如fanutil、psuutil等
然后寻找/usr/lib/python2.7/dist-packages/对应的文件目录,进去查看是否拥有
init.py,若有,则调用该目录下的main.py作为参数传入到/usr/bin文件中
#!/usr/bin/env python
"""
main.py
Command-line utility for interacting with fan in SONIC
"""
'''
译文:在SONIC中与风扇交互的命令行实用程序
'''
=================================================
@staticmethod 是一个装饰器,用于定义静态方法。静态方法是属于类而不是实例的方法,因此它们可以直接通过类名调用,而不需要创建类的实例
静态方法与普通方法和类方法相比具有以下特点:
静态方法不需要访问实例的属性或方法,因此不需要传递 self 或 cls 参数。
静态方法不能访问类的实例属性,也不能访问类的其他方法,只能访问类的静态属性和其他静态方法。
静态方法可以通过类名直接调用,也可以通过实例调用
@classmethod 是一个装饰器,用于定义类方法。类方法是属于类而不是实例的方法,因此它们可以直接通过类名调用,而不需要创建类的实例
类方法与普通方法和静态方法相比具有以下特点:
类方法可以访问类的属性和方法,但不能访问实例的属性和方法。
类方法的第一个参数是类本身,通常被命名为 cls。通过该参数,可以在类方法中访问类的属性和调用类的方法。
类方法可以通过类名直接调用,也可以通过实例调用
在Python中,类方法、静态方法和普通方法是三种不同类型的方法,它们之间有以下区别:
类方法(@classmethod):
cls
。静态方法(@staticmethod):
self
或 cls
参数。普通方法:
self
。总结:
=================================================
【python相关函数】
str.strip() //去除字符串两边的空格
str.startswitch(“xxx”) //判断字符串是否以指定字符或子字符串开头
str.startswitch(“xxx”, start, end) //start:索引头 end:索引尾
str[0:6].startswitch(“xxx”) //只索引 0~6
split(“xxx”) //通过指定分隔符对字符串分割,返回分割后的字符串list
split(“xxx”,count) //"xxx"是用于分割字符串的分隔符,count是可选的参数,用于指定最大拆分次数
os.path.split() //按照路径将文件名和路径分隔开
raise //主动触发异常,以便在代码中进行错误处理或异常处理
[int(i) for i in list] //列表推导式(表达式和迭代器)
表达式:int(i) 将迭代器的每个元素i都转换为整数类型
迭代器:for i int list 对列表list中的每个元素进行迭代,并将当前元素赋值给变量i
status = ‘,’.json(func()) //其中函数func()返回一个可迭代对象(如列表、元组)
json() //将可迭代对象中的元素连接成一个字符串,语法是
separator.join(iterable),其中separator 是指定的分隔符,iterable 是要连接的可迭代对象
例如,假设 func() 返回的是一个列表 [‘a’, ‘b’, ‘c’];
那么 ‘,’.join(func()) 的结果将是字符串 ‘a,b,c’,并将其赋值给变量 status
int(v, 16) //将一个十六进制字符串转换为整数(转换的值, 基数|进制)
struct.pack(‘格式字符串’, ‘转换的数据’) //将数据按照指定的格式转换为二进制字符串 [8s:长度为8的字符串 | B:无符号字节类型(8位) | >H:大端字节序的无符号短整数格式指令(16位)]
value.encode() //将字符串编码为字节序列
在Python中,字符串是以Unicode字符表示的,而字节序列是以二进制数据表示的。encode()方法可以将字符串转换为指定编码的字节序列
self.data.append() //Python列表(一种可变的有序数据类型,可以存储多个元素)方法,用于向列表末尾添加元素
os.path.join(path1, path2) //根据当前操作系统的规则,os.path.join()函数会自动选择适当的路径分隔符,然后返回一个有效的路径
pattern.match(value) //检查给定的字符串value是否与模式匹配
return -1, 0, 0 //可以输出错误信息并返回相应的错误码和值,即python中可以返回多个值
re //Python标准库中的一个模块,用于处理正则表达式
compile() //re模块中的一个函数,用于将正则表达式模式编译为一个可重复使用的正则表达式对象
readlines() //文件对象的一个方法,用于读取文件的所有行,并将其以列表的形式返回
list() //将可迭代对象(如字符串、元组、字典等)转换为列表
with open(‘example.txt’, ‘r’) as file:
# 在这里进行文件操作
# 文件会在代码块结束后自动关闭
add_option() //是argparse模块中的一个方法,用于向解析器添加命令行选项
optparse.OptionParser() //解析命令行选项和参数
list() //将一个可迭代对象(如字符串、元组或其他可迭代的对象)转换为一个列表
range() //生成一个整数序列,e.g. range(5)会生成0,1,2,3,4
range(start, end) //生成一个整数序列,e.g. range(0,2)会生成0,1
lower() //将字符串中的所有字符转换为小写字母,并返回一个新的字符串
upper() //将字符串中的所有字符转换为大写字母,并返回一个新的字符串
getattr(要获取属性值的对象, 要获取的属性名称)
//用于获取对象的属性值。它接受两个参数:对象和属性名称,并返回该属性的值
dir(signal) //返回一个包含指定对象(signal)所有属性和方法名称的列表。在这里,它返回了 signal 对象的所有属性和方法的名称列表
startswith(‘xxx’) //字符串方法,用于检查字符串是否以指定的前缀开头。在这里,它用于检查是否以 ‘xxx’ 开头
e.g.
for i in dir(signal) if i.startswith(‘TAR’) and ‘’ not in n
遍历 signal 对象的所有属性和方法名称,筛选出以 ‘TAR’ 开头且不包含 '’ 的属性名称
isinstance() //用于检查一个对象是否属于指定的类或类型
enumerate() //将一个可迭代对象组合为一个索引序列和一个元素序列,常用于在循环中获取元素的索引和值
e.g.: enumerate(iterable, start=0)
iterable是一个可迭代对象,可以是列表、元组、字符串等。start是可选参数,表示索引的起始值,默认为0
在python中,冒号(:)用于切片操作。在给定的列表、字符串或其他可迭代对象中,可以使用切片操作来选择一部分元素
my_list = [1, 2, 3, 4, 5]
print(my_list[2:]) # 输出:[3, 4, 5]
ord() //返回了相应字符的ASCII码值
time() //返回当前时间的时间戳,即从1970年1月1日午夜(格林威治标准时间)到当前时间的秒数
input() //用于从用户获取输入
one_dict = {}
one_dict.update({two_dict:{}})
这两行代码是一个字典的更新操作,用于向字典中添加一个新的键值对。
具体来说,update()方法是字典对象的一个内置方法,用于将一个字典的键值对添加到另一个字典中。
它接受一个字典作为参数,将该字典中的键值对添加到调用该方法的字典中。
在这个例子中,update({two_dict:{}})的意思是将一个空字典作为值,以键名two_dict作为键,添加到当前字典中。如果当前字典中已经存在dev键,则会更新其对应的值为一个空字典
threading.Event() //用于创建一个Event对象。Event是threading模块中的一个类,用于线程之间的同步,例如等待和触发事件
e.g.
import threading
#创建Event对象
event = threading.Event()
#线程函数
def thread_func():
print(“Thread is waiting for event to be set”)
event.wait()
print(“Event is set. Thread is continuing”)
#创建线程
thread = threading.Thread(target=thread_func)
#启动线程
thread.start()
#触发事件
event.set()
#等待线程结束
thread.join()
※※※self是一个特殊的参数,用于表示对象本身。当我们在类的方法中使用self时,它指的是调用该方法的实例对象
// //是Python中的整数除法运算符,它会将除法的结果向下取整为最接近的整数,
e.g.
5 // 2 == 2
-5 // 2 == -3
sed ‘s/onie_machine=//’
是一个用于在命令行中使用sed(流编辑器)的命令。
作用是将输入中的每一行中的 onie_machine= 替换为空字符串。
在这个命令中,s/ 表示替换操作的开始,onie_machine= 是要被替换的模式,// 表示替换为空字符串。
这个命令可以用于在文本文件或者输出流中删除特定的字符串
r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}"
r是一个前缀,表示后面的字符串是一个原始字符串;
在原始字符串中,反斜杠字符\不会被解释为转义字符,而是作为普通字符处理。
在正则表达式中,使用原始字符串可以避免对特殊字符进行额外的转义。
"^\s*"是一个正则表达式模式,用于匹配以零个或多个空白字符开头的字符串。
其中,^表示匹配字符串的开头,\s表示匹配任意空白字符(包括空格、制表符、换行符等),*表示匹配前面的元素零次或多次。
[0-9a-fA-F]{2,2}:是一个正则表达式模式,用于匹配两位十六进制数后跟一个冒号的字符串。
其中,[0-9a-fA-F]表示匹配一个十六进制字符(0-9或a-f或A-F),{2,2}表示匹配前面的元素恰好两次,即两位十六进制数。
综合起来,re.compile(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}")
编译了一个正则表达式模式,
用于匹配符合MAC地址格式的字符串。
这个模式首先匹配以零个或多个空白字符开头的字符串,然后匹配五组由冒号分隔的两位十六进制数,最后匹配一个两位十六进制数。
在正则表达式中,的位置非常重要,它只能匹配字符串的开头位置。如果将放在其他位置,它就会失去特殊的含义,变成普通字符的匹配
ERR_UNKNOWN = 1
exit_code = ERR_UNKNOWN
控制守护进程被设计为永远不会退出,它必须在退出时总是返回非零退出代码,以便监督系统将自动重启它。
def try_get(callback, default=‘N/A’):
try:
ret = callback()
if ret is None:
ret = default
except NotImplementedError:
ret = default
return ret
自定义装饰器的步骤如下:
1.创建一个函数,作为装饰器的主体。
2.在装饰器函数内部定义一个嵌套函数,用于接收原函数作为参数,并在其周围添加额外的功能或逻辑。
3.在装饰器函数的末尾返回嵌套函数。
4.将装饰器应用到需要装饰的函数上,使用@符号将装饰器函数放在原函数的前面。
def my_decorator(func):
def wrapper(*args, **kwargs):
print(“Before function call”)
result = func(*args, **kwargs)
print(“After function call”)
return result
return wrapper
@my_decorator
def my_function():
print(“Inside function”)
my_function()
from abc import ABCMeta, abstractmethod
abc是Python的内置模块,用于实现抽象基类(Abstract Base Classes)的功能
在Python中,抽象基类是一种特殊的类,不能直接实例化,而是用作其他类的基类
抽象基类定义了一组规范(接口),子类必须实现这些规范才能被认为是有效的
abc模块提供了ABCMeta元类和abstractmethod装饰器,用于定义抽象基类和抽象方法
ABCMeta是一个元类,用于创建抽象基类
abstractmethod是一个装饰器,用于标记抽象方法
async:async 是一个关键字,用于定义一个协程函数。
协程函数是一种特殊的函数,可以在其中使用 await 关键字来暂停执行,并等待其他协程或异步操作完成。
Python 3.5 及更高版本引入了 async 和 await 关键字,用于定义和使用协程。
finally:finally 是一个关键字,用于定义一个 try 语句块的最后一个代码块。
不论是否发生异常,finally 代码块中的代码都会被执行。
finally 用于执行一些清理操作,例如关闭文件或释放资源。
nonlocal:nonlocal 是一个关键字,用于在嵌套函数中引用外部函数的局部变量。
在嵌套函数中,如果要修改外部函数的局部变量,可以使用 nonlocal 关键字。
nonlocal 常用于闭包函数中。
yield:yield 是一个关键字,用于定义一个生成器函数。
生成器函数是一种特殊的函数,可以使用 yield 关键字来暂停执行,并返回一个值给调用者。
每次调用生成器函数时,都会从上次暂停的位置继续执行。
通过迭代生成器函数,可以逐个获取生成器函数返回的值,而不是一次性返回所有值
静态方法是属于类的方法,而不属于类的实例。它们不会接收隐式的第一个参数(通常是self),
因此在静态方法中不能访问实例变量或调用实例方法,可以用类名直接调用静态方法MyClass.my_static_method()
dmidecode -t 11是一个命令,用于显示系统中的内存模块信息
-t 11是dmidecode命令的一个选项,表示只显示类型为11的DMI信息,即内存模块信息
python自带的内置装饰器
@abstractmethod:标记抽象方法
@staticmethod:定义静态方法
【python脚本解释器】
根据您提供的输出,脚本文件/usr/local/bin/111
具有可执行权限,并且文件所有者是root用户。
在这种情况下,如果您尝试执行脚本/usr/local/bin/111
,但是遇到了from: command not found
和import: command not found
的错误提示,这可能是因为脚本文件的Shebang(解释器指令)不正确。
请确保脚本文件/usr/local/bin/111
的第一行包含正确的Shebang,例如:
#!/usr/bin/env python
或
#!/usr/bin/python3
这将指定使用Python解释器来执行脚本文件。
如果问题仍然存在,请提供脚本文件的完整代码,以便我可以更好地帮助您解决问题。
【shell脚本解释器】
Shell脚本也可以使用Shebang行来指定脚本的解释器。Shebang行是以#!
开头的一行注释,用于告诉操作系统应该使用哪个Shell解释器来执行脚本。
例如,如果您希望使用Bash解释器来执行Shell脚本,可以在脚本的第一行添加以下Shebang行:
#!/bin/bash
这告诉操作系统使用/bin/bash
路径下的Bash解释器来执行脚本。
其他常见的Shell解释器包括/bin/sh
(默认Shell解释器)和/bin/zsh
(Zsh解释器)。您可以根据需要选择适当的解释器。
Shebang行必须位于脚本的第一行,并且以#!
开头,后面紧跟着解释器的路径。Shebang行的作用是在执行脚本时自动调用正确的解释器,而无需手动指定解释器。
请注意,Shebang行只对可执行脚本文件有效。对于以.sh
为扩展名的Shell脚本文件,您还需要为文件添加可执行权限(例如使用chmod +x script.sh
命令)才能直接执行脚本。
【模块…】
<<…argparse模块…>>
argparse模块是命令行选项、参数和子命令解析器, 可以让人轻松编写用户友好的命令行接口
适用于代码需要频繁地修改参数的情况
parser = argparse.ArgumentParser(description=‘命令行描述’)
在顶层的解析器下,先定义一个subparsers,它是一个子命令解析的对象,用来产生子命令解析器
(注意,每个解析器,只能有一个subparsers)
subparsers = parser.add_subparsers()
在subparsers下,分别定义所需要的子解析器(一个subparsers下可以有多个parser),
子解析器间是互斥的关系,一个时刻只能匹配一个
port_status_parser = subparsers.add_parser(‘port_status’, help=‘test poee port_status firstport endport firstvoltage endvoltage firstelec endelec’)
添加参数
port_status_parser.add_argument(‘firstport’, type=int)
set_defaults() 方法可用于指定命令行参数的默认值
port_status_parser.set_defaults(func=port_status)
属性给与args实例:
把parser中设置的所有"add_argument"给返回到args子类实例当中,
那么parser中增加的属性内容都会在args实例中,使用即可
args = parser.parse_args()
parser.parse_args()
subprocess.run函数是用于执行外部命令并等待命令结束的函数
它会返回一个CompletedProcess类型的对象,表示执行完毕的进程。
这个对象包含了执行结果的相关信息,比如返回码、标准输出和标准错误输出等。
CompletedProcess类型对象包含以下属性:
subprocess.run函数与subprocess.Popen函数的区别:
1)
subprocess.run是一个高级接口,它会等待命令执行完毕并返回结果
subprocess.Popen是一个低级接口,它创建了一个新的进程并返回一个Popen对象,需要通过Popen对象的方法来获取命令的输出和状态。
output, _ = ret.communicate()
这行代码的意思是使用communicate()方法获取ret对象(即subprocess.run返回的CompletedProcess对象)的标准输出,
并将结果赋值给output变量。在这个例子中,使用下划线`_表示忽略标准错误输出
communicate()方法是用于和子进程进行交互的方法。当调用communicate()方法时,它会向子进程的标准输入发送数据(如果有的话),然后等待子进程执行完毕并获取标准输出和标准错误输出。
最后返回一个元组,包含标准输出和标准错误输出的字节串。