python语法杂记

python基础:

1)常用的数据结构(集合)

数据双向链表queue:队列和栈
排序字典:orderrdDict
计数器:counter

2)模块

什么是模块?
什么是包及如何使用第三方包?
模块使用总结?

3)函数

自定义函数一般格式;
函数参数中的不可变数据类型和可变数据类型;
变量作用域;

4)条件判断

一般格式;
边界条件(值比较和逻辑判断)
多个条件判断

5)循环(批量处理数据)

6)数据类型

容器,布尔,None,数字,字符串。
容器:列表,元组,集合,字典
管理容器的方法:如何定义容器?容器的四个操作:增删改查

【数据类型】

  1. 加号 + 是字符串的连接符, 星号 * 表示复制当前字符串,紧跟的数字为复制的次数;

  2. Python 使用反斜杠()转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串

  3. Python中的字符串、元组不能改变

  4. 数字型包括int float bool complex(复数)

  5. 内置的 type() 函数可以用来查询变量所指的对象类型

  6. 当你指定一个值时,Number 对象就会被创建,可以通过使用del语句删除单个或多个对象

  7. 数字运算
    2/4 ##除法,得到一个浮点数
    2//4 ##除法,得到一个整数
    2 ** 5 ##乘方

  8. 列表[]
    list = [‘1234’, 234, 2.3, ‘adc’, [123,‘abc’]]
    列表可以完成大多数集合类的数据结构实现;
    列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)
    和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表
    索引值以 0 为开始值,-1 为从末尾的开始位置
    print (list * 2) ##输出两次列表
    print (list + list) ##连接列表
    del list[2] ##删除列表第三个元素
    list.append(‘dfg’) ##增加列表元素

  9. 元组()
    元组写在小括号()内,元素之间用逗号隔开
    元组(tuple)与列表类似,不同之处在于元组的元素不能修改
    元组与字符串类似,可以被索引且下标索引从0开始,-1 为从末尾开始的位置也可以进行截取
    可以把字符串看作一种特殊的元组

  10. 集合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 ##删除字典

  1. python魔法方法:
    1.doc: 描述类信息
    2.str: 对象的描述信息
    3.module: 表示当前操作的对象在那个模块
    4.class: 表示当前操作对象的类是什么

  2. python的%:格式化输出
    %[(name)][flags][width].[precision]typecode
    (name)为命名
    flags: + 右对齐 - 左对齐 ''正数填充一个空格,从而与负数对齐 0 使用0填充
    width: 宽度
    precision: 小数点后精度
    typecode: 数据类型

  3. python函数

  1. 未知的参数数量可通过将 * 放在参数之前来获得未知数量的参数
def func(*names):
    i = 0
    while len(names) > i:
        print(names[i], end=', ') #The following is python3's syntax
        #print names[i],          #The following is python2's syntax
        i += 1

func('Steve', 'Bill') 
func('Steve', 'Bill', 'John', 'Amir') 
  1. 前缀为**的参数,这种类型的参数将初始化为新的有序映射,接收任何多余的关键字参数,默认为相同类型的新空映射
def func(**person):
    print('Hello ', person['firstname'],  person['lastname'])

func(firstname='Steve', lastname='Jobs')
func(lastname='Jobs', firstname='Steve')
func(firstname='Bill', lastname='Gates', age=55) 
func(firstname='Bill') # raises KeyError 参数只能多于,不能少于

3) python有带默认值的参数
def func(name = 'Guest'):
    print ('Hello', name)

func()
func('Steve')
  1. Lambda函数和匿名函数
    lambda函数只能有一个表达式。显然,它不能替代函数体可能有条件、循环等的函数
    square = lambda x : x * x #参数:返回值
    square = lambda : x * x # :返回值
    可声明一个 lambda 函数,并以匿名函数的形式调用它,而无需将其赋给变量
    (lambda x : x * x)(5) 结果为25
    在 Python 中,函数是第一类公民,这意味着就像文字一样,函数也可以作为参数传递。
    当我们想要将函数作为参数之一提供给另一个函数时,lambda 函数非常有用。
    我们可以将 lambda 函数作为匿名函数传递给另一个函数。
def dosomething(fn):
    print('Calling function argument:')
    fn()
dosomething(lambda : print('Hello World')) #The following is python3's syntax
myfn = lambda : print('Hello World') 
dosomething(myfn) #The following is python3's syntax

输出:

Calling function argument:
Hello World
Calling function argument:
Hello World

16. python 中的__main__和__name__

  1. python 包含名为__name__的特殊变量,该变量包含作为字符串执行的代码的范围。
    __main__是顶层代码执行的顶层作用域的名称。
    解释器 Shell 中执行的代码(所有的功能和模块)的范围将是__main__!!!
  2. __name__的值允许 Python 解释器确定模块是否是可执行脚本。
    如果其值为main,将执行函数定义之外的语句。
    如果没有,模块的内容将被填充到顶层模块(或解释器名称空间)中,而不包含可执行部分
  3. 从命令提示符/终端执行的 Python 脚本文件将在顶层作用域__main__作用域下执行。
    但是,导入模块将在模块自己的范围内执行。因此,顶层范围将是__main__,第二个范围将是模块的范围。
    因此,使用特殊变量__name__和顶级范围__main__增加了可重用性。
    Python 脚本文件可以作为独立脚本从命令提示符/终端执行,也可以作为模块导入!!!

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()函数的参数,具体含义如下:

  1. r'(-script\.pyw?|\.exe)?$':这是一个正则表达式模式,用于匹配需要替换的字符串。
    在这个例子中,它匹配以"-script.py"或"-script.pyw"或".exe"结尾的字符串。这
    个模式中的各个部分的含义如下:
  • (-script\.pyw?|\.exe):匹配"-script.py"或"-script.pyw"或".exe"。
  • ?:表示前面的字符可选,即匹配"pyw"或"py"。
  • $:表示匹配字符串的结尾。
  1. '':这是一个空字符串,用于替换匹配到的字符串。
  2. sys.argv[0]:这是需要进行替换操作的字符串,也就是sys.argv[0]。它表示当前脚本的文件名

综合起来,这行代码的作用是将sys.argv[0]中以"-script.py"或"-script.pyw"或".exe"结尾的部分
替换为空字符串。也就是将脚本文件名中可能包含的后缀名或命令行参数去除,
得到一个更简洁的文件名。

17. python 生成器函数

  1. 生成器是一种特殊类型的函数,它不返回单个值,而是返回一个包含一系列值的迭代器对象
    在生成器函数中,使用yield语句,而不是返回语句
    def mygenerator():
    print('First item')
    yield 10
    
  2. 生成器函数不能包含return关键字。如果包含它,那么它将终止函数。
    yield和return的区别在于yield返回值并暂停执行,同时保持内部状态,而return语句返回值并终止函数的执行
  3. 生成器相对于迭代器的优点之一是元素是动态生成的。由于下一项只在第一个项被消耗后生成,因此它比迭代器更节省内存。
  4. 生成器函数也可以使用 for循环
def get_sequence_upto(x):
    for i in range(x):
        yield i 

当遇到yield关键字时,其执行被暂停。这将迭代器流的第一个值发送到调用环境。但是,局部变量及其状态保存在内部
5) Python 还提供了一个生成器表达式,这是定义简单生成器函数的一种更短的方式。生成器表达式是匿名生成器函数
(x*x for x in range(5))是一个生成器表达式。表达式的第一部分是yield值,第二部分是带有集合的 for循环

18. python 列表推导

  1. Python 中的列表推导是一种简单而紧凑的语法,用于从字符串或其他列表创建列表
    [expression for element in iterable if condition]
    列表推导语法包含三个部分:一个表达式,一个或多个for循环,以及可选的一个或多个 if 条件
    列表推导必须在方括号[]内
    第一个表达式的结果将存储在新列表中
    for循环用于迭代可选地包含 if 条件的可迭代对象
    找到从 0 到 20 的偶数:
even_nums = []                                            #普通写法
for x in range(21):
    if x%2 == 0:
        even_nums.append(x)
print(even_nums)

even_nums = [x for x in range(21) if x%2 == 0]            #列表推导式
print(even_nums) 
  1. 适用于数字列表、也适用于字符串列表、也适用于嵌套循环的列表推导
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%2==0 if x%5==0]
print(nums)
  1. 列表推导的应用之一是将包含多个列表的列表展平为单个列表
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] 

19. python中的异常处理

  1. 单个try块可以有多个except块, 单个else块、单个finally块
try:
    ...
except:
    ...
except:
    ...
else:
    ...
finally:
    ...

两种执行情况: 正常(try->else->finally), 异常(try->except->finally)
2) 引发异常关键字raise
raise关键字:用于异常处理的上下文中, 它导致显式生成异常, 隐式引发内置错误

try:
    ...
    if (...)
        raise A               #显示引发A类型异常
except A:
    ...
except B:
    ...
else:
    ...
finally:
    ...

20. python 文件输入/输出—读写文件

  1. IO模块提供了三种IO操作的方法:原始二进制文件、缓冲二进制文件、文本文件
  2. read(chars):从当前位置开始读取指定数量的字符
    read():读取一个文件的全部内容, 直到 EOF 为字符串
    EOF(End of File)字符是一个特殊的字符,用于表示文件的结束
    readline():读取从当前读取位置开始直到换行符的字符
    readlines():读取所有行,知道文件结束,并返回一个list对象
    white():将字符串写入流,并返回写入的字符数
    whitelines(__LINE__):想流中写入一个行列表, 每行的末尾必须有一个分隔符

21. python的正则表达式

正则表达式是定义搜索模式的字符序列,主要用于在搜索引擎和文本处理器中执行查找和替换操作
Python 通过作为标准库的一部分捆绑的re模块提供正则表达式功能

  1. 原始字符串:字符串前 + r
    正常字符串和原始字符串的区别:
    在于 print() 函数中的正常字符串翻译转义字符(如\n、\t等)的值,原始字符串中的值则不是
  2. 元字符:* . ^ $ + ? [] \ | () {} **
    备注:大小写敏感
    [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 : 词与非词的界限
  3. re.match(pattern, str):试图找出指定的模式是否出现在给定字符串的开头

例1:

from re import match

mystr = "Welcome to TutorialsTeacher"
obj1 = match("We", mystr)
print(obj1)
obj2 = match("teacher", mystr)
print(obj2) 

输出:
<re.Match object; span=(0, 2), match='We'>
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)
  1. re.search(pattern, str):给定字符串的任意位置搜索指定的模式,并在第一次出现时停止搜索
  2. re.findall(pattern, str):给定字符串的任意位置搜索指定的模式,直至搜索完字符串后才停止搜索
  3. re.finditer(pattern, str):返回目标字符串中所有匹配项的迭代器对象
  4. re.split(pattern, str):等价str对象的 split() 方法
    每次发现空白时, 它都会拆分给定的字符串, 并去除列表中的pattern
  5. 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))

22. python 多线程

  1. 螺纹类型:内核级线程、用户级线程
    在螺纹类型中,内核线程和用户线程是两种不同的线程类型,它们的区别主要体现在 线程的管理和调度方式 上。
    内核线程(Kernel Thread):
  • 由操作系统内核直接管理和调度
  • 内核线程的创建、销毁和切换都由操作系统内核完成
  • 内核线程的创建和销毁需要系统调用,开销较大
  • 内核线程可以并行执行,适合多核处理器
  • 内核线程的切换需要切换上下文(Context Switching),开销较大

用户线程(User Thread):

  • 由用户程序库(例如线程库)管理和调度
  • 用户线程的创建、销毁和切换由用户程序库完成, 不需要系统调用
  • 用户线程的创建和销毁开销较小
  • 用户线程不能并行执行,只能在单个内核线程中轮流执行
  • 用户线程的切换不需要切换上下文,开销较小

总的来说,内核线程由操作系统内核管理和调度,具有更高的开销和更好的并行性能,但线程的创建和切换开销较大;
而用户线程由用户程序库管理和调度,开销较小,但并不能真正并行执行,只能在单个内核线程中轮流执行

在实际应用中,通常会将用户线程映射到内核线程上运行,以充分利用多核处理器的并行性能。这种方式称为"一对一"模型
还有其他线程模型,如"多对一"模型和"多对多"模型,它们的线程管理和调度方式有所不同
2) python多线程的好处:
一个进程中的多个线程共享相同的数据空间,因此可以比单独的进程更容易地共享信息或相互通信。
线程不需要太多内存开销;就内存需求而言,它们比进程便宜。
多线程程序可以在具有多个 CPU 的计算机系统上运行得更快,因为这些线程可以同时执行

23. python中的锁对象—线程同步

  1. 原语锁
import threading

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 

24. python 使用事件对象的线程同步

  1. 事件类对象提供一种简单的机制, 用于线程之间的通信, 其中一个线程发出事件信号, 而其他线程等待他
    初始化事件对象:内部标志默认为假
import threading

are_you_coming = threading.Event()

isSet():当且仅当内部标志为真时,此方法返回真
set():当对任何事件对象调用此方法时,内部标志被设置为 true, 唤醒线程
clear():将内部标志重置为 false, 随后对调用clear()的事件调用wait()的线程将阻塞,直到内部标志再次不为真
wait():
让任何线程都等待一个事件时:
在内部标志设置为 false 的事件上调用这个方法,这样做将阻塞线程,直到事件的内部标志为 true

25. python的计时器对象

定时器对象是使用Thread类的子类Timer类创建的
使用这个类,我们可以为任何应该在一定时间后运行的操作设置一个延迟(计时器),并且可以在该延迟期间轻松取消
计时器通过调用其start()方法启动,就像普通线程一样;
定时器线程可以通过调用其cancel()方法来停止(在其动作开始之前)

threading.Timer(interval, function, args=[], kwargs={})
创建一个计时器对象,在经过interval秒后,该对象将运行带有参数args和关键字参数kwargs的功能
start():启动计时器对象的执行,当我们调用这个方法时,定时器对象启动它的定时器

cannel():停止计时器并取消计时器对象操作的执行。
这只有在计时器尚未执行其动作的情况下才会起作用,如果计时器已经执行了其动作,则 cancel() 方法将不起作用

25. python 面向对象

  1. 构造器
    在 Python 中,每当类的新对象被实例化时,都会自动调用构造器方法
    构造器必须有一个特殊的名称__init__()和一个特殊的参数self

  2. 类方法
    一个类的受保护成员可以从该类内部访问, 并且也可用于其子类,
    不允许其他环境访问它,这使得父类的特定资源能够被子类继承。
    Python 让实例变量受保护的惯例是给它添加前缀 _(单下划线),
    这有效地防止了它被访问,除非它来自子类。

  3. Python 没有任何机制可以有效地限制对任何实例变量或方法的访问
    ** Python 规定了一个惯例,在变量/方法的名称前加一个或两个下划线,**
    以模仿受保护和私有访问说明符的行为!!!
    _变量名:表示受保护的变量
    __变量名:表示私有的变量
    负责任的程序员不会从类外访问和修改以_为前缀和以__为前缀的实例变量!!!

    Python 执行私有变量的名称管理, 如下:
    每个带_下划线的成员都和不带_下划线的变量访问方法一样, 即std.name | std._name
    每个带双下划线的成员都将被更改为_object._class__variable!!!
    变量前面的双下划线__使其成为私有的。 强烈建议不要在类外触碰。任何尝试都会导致属性错误!!!

26. python中的装饰器

在编程中,装饰器是一种设计模式, 它可以动态地向对象添加额外的职责

  1. python中的装饰器是一个接收另一个函数作为参数的函数,
    参数函数的行为是有装饰器扩展的,并没有实际修改它,即
    可以使用@decorator语法在函数上应用decorator函数
  2. python中的装饰器可以使用@decorator_function_name语法在任意适当的函数上定义,以拓展底层函数的功能
def mydecorator(fn):
    def inner_function():
        func()
        print ('How are you?')
    return inner_function
@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 
  1. 内置装饰器
    python库包含很多内置装饰器, 作为定义属性、类方法、静态方法等的快捷方式
    装饰者 描述
    @property 将方法声明为属性的setter或getter方法
    @classmethod 将方法声明为类的方法, 可以使用类名调用该方法
    @staticmethod 将方法声明为静态方法(使用类名而不是实例来调用静态方法)

  2. 类的方法可以分为三种类型:

实例方法(Instance Method):
这些方法是最常见的方法类型,它们需要通过类的实例来调用。
实例方法的第一个参数通常被命名为 self,它指代的是实例本身。
实例方法可以访问和修改实例的属性。

类方法(Class Method):
这些方法使用 @classmethod 装饰器进行修饰,可以通过类名或实例来调用。
类方法的第一个参数通常被命名为 cls,它指代的是类本身。
类方法可以访问和修改类的属性。

静态方法(Static Method):
这些方法使用 @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中,类方法、静态方法和普通方法是三种不同类型的方法,它们之间有以下区别

  1. 类方法(@classmethod):

    • 类方法是属于类的方法,而不是实例的方法。
    • 类方法的第一个参数是类本身,通常被命名为 cls
    • 类方法可以访问类的属性和调用类的方法。
    • 类方法可以通过类名直接调用,也可以通过实例调用。
    • 类方法通常用于对类属性进行操作或提供类级别的功能。
  2. 静态方法(@staticmethod):

    • 静态方法是属于类的方法,而不是实例的方法。
    • 静态方法不需要访问实例的属性或方法,因此不需要传递 selfcls 参数。
    • 静态方法不能访问类的实例属性,也不能访问类的其他方法,只能访问类的静态属性和其他静态方法。
    • 静态方法可以通过类名直接调用,也可以通过实例调用。
    • 静态方法通常用于提供与类相关的功能,但不需要访问实例属性或方法。
  3. 普通方法:

    • 普通方法是属于实例的方法,只能通过实例调用。
    • 普通方法的第一个参数是实例本身,通常被命名为 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键,则会更新其对应的值为一个空字典

python的线程

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 foundimport: 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类型对象包含以下属性:

  • args:执行的命令,以列表形式存储
  • returncode:命令的返回码,通常用于判断命令是否执行成功
  • stdout:标准输出的内容,以字节串形式存储
  • stderr:标准错误输出的内容,以字节串形式存储

subprocess.run函数与subprocess.Popen函数的区别:
1)

subprocess.run是一个高级接口,它会等待命令执行完毕并返回结果
subprocess.Popen是一个低级接口,它创建了一个新的进程并返回一个Popen对象,需要通过Popen对象的方法来获取命令的输出和状态。

output, _ = ret.communicate()
这行代码的意思是使用communicate()方法获取ret对象(即subprocess.run返回的CompletedProcess对象)的标准输出,
并将结果赋值给output变量。在这个例子中,使用下划线`_表示忽略标准错误输出

communicate()方法是用于和子进程进行交互的方法。当调用communicate()方法时,它会向子进程的标准输入发送数据(如果有的话),然后等待子进程执行完毕并获取标准输出和标准错误输出。
最后返回一个元组,包含标准输出和标准错误输出的字节串。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值