Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。Python 由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。像 Perl 语言一样, Python 源代码同样遵循 GPL(GNU General Public License) 协议。

官方宣布,2020 年 1 月 1 日, 停止 Python 2 的更新。Python 2.7 被确定为最后一个 Python 2.x 版本。

笔者使用的是python3.8该博文并不适合完全零基础的读者,并且不会将所有的python基础全部展示出来,该博客旨在解决一些python的关键用法,python零基础请移步以下网址:

  1. Python3 教程 | 菜鸟教程 (runoob.com)

  2. Python 教程 (w3school.com.cn)

安装

安装python有两种方式

  1. 直接安装python环境,网址:Download Python | Python.org

  2. 安装conda环境,搭建虚拟python环境,推荐这个办法搭建python环境,可使用不同python环境进行编程,具体搜笔者的另外一个博客,Anaconda

命令行运行python

在Linux或macOS系统中,您可以使用命令行来运行Python文件。步骤如下:

  1. 打开终端。

  2. 使用cd命令切换到文件所在目录。

  3. 输入 python 文件名.py,并按Enter键运行。

例如,如果文件名为test.py,并且它位于 /home/user/PythonProjects 目录下,可以输入以下命令来运行该文件:

cd /home/user/PythonProjects
python test.py
python -m test

也可以用 python3 来运行

cd /home/user/PythonProjects
python3 test.py

或者在文件前面加上python路径来运行

/usr/bin/python test.py

python -m 模块名python 模块名.py 两种方式都可以运行Python文件,但它们有一些区别。

  1. python -m 模块名 会自动搜索 sys.path,在其中寻找对应的模块文件,并运行它。它还可以运行没有 main.py 的模块。

  2. python 模块名.py 直接运行指定的文件。需要知道文件的确切路径。

所以,当你的模块被其他模块导入时,你可以使用 python -m 模块名 来运行你的模块,而不需要知道它的具体路径。

如果你只是想运行一个特定的脚本,你可以使用 python 文件名.py

命令行传参

在文件运行时,可以使用 sys.argv 列表来接收参数。sys.argv[0] 包含文件名,而后面的参数存储在 sys.argv[1] 到 sys.argv[n]。例如,在命令行中运行 Python 文件 test.py,并传递参数 arg1 和 arg2:

python test.py arg1 arg2

在 test.py 中,可以使用 sys.argv 列表来访问命令行参数。:

import sys
print(sys.argv[1]) #arg1
print(sys.argv[2]) #arg2

如果您希望程序能够处理更多的命令行选项和参数,可以使用argparse库。此库可以帮助您定义和处理命令行参数,并提供有关如何使用参数的帮助信息。例如:

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

在命令行中运行

python test.py 1 2 3 --sum # 输出6

这样就可以使用命令行来运行Python文件并传递参数了。

注释

引用:Python代码注释规范代码实例解析 - 知乎 (zhihu.com)

  • 注释不是越多越好。对于一目了然的代码,不需要添加注释。

  • 对于复杂的操作,应该在操作开始前写上相应的注释。

  • 对于不是一目了然的代码,应该在代码之后添加注释。

  • 绝对不要描述代码。一般阅读代码的人都了解Python的语法,只是不知道代码要干什么

单行注释

描述某个变量(某行代码)的作用

第一种写法:

# 注释
ui = 1

第二种写法:

ui = 1 # 注释

突出某段代码的重要性

# ==================
# 请勿删除该变量!!!!
# ==================
ui = 1

类注释

描述某个类的作用

格式如下:

"""类用处"""

使用实例:

class test:
    """类用处"""
    pass

方法注释

描述某个方法的作用

DocStrings 文档字符串使用惯例:它的首行简述函数功能,第二行空行,第三行为函数的具体描述。

格式如下(reST风格):

"""
方法的用处

:param parm: 形参的用处
:return: 返回的数据
"""

这是现在流行的一种风格,reST风格,Sphinx的御用格式,比较紧凑。

  • param为说明传入的形参

  • return为说明返回的数据

使用实例:

def test(self,parm01,parm02):
    """
    方法的用处
    
    :param parm01: 形参的用处01
    :param parm02: 形参的用处02
    :return: 返回的数据
    """
    pass

基本数据类型

Python3 中有六个标准的数据类型:

  • Number(数字)

  • String(字符串)

  • List(列表)

  • Tuple(元组)

  • Set(集合)

  • Dictionary(字典)

Python3 的六个标准数据类型中:

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);

  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

数组

python数组用于在单个变量中存储多个值

列表(List)

在 Python 中,列表是一种常用的数据类型,它可以存储多个元素。列表中的元素可以是任意类型,并且列表本身可以嵌套。

  • 新建一个包含数字的列表

number = [1,2,3,4,5,6,7,8]
  • 返回/修改列表中某下标的值

number[0] # 返回第一个列表中的值
number[-1] # 返回倒数第一个列表中的值
number[1:5] # 返回列表的第二个到第六个的值
number[1] = 1 # 修改列表某下标的值

其中number[1:5]为列表切片操作,列表切片是通过使用下标范围来访问列表中的一个子集的过程。语法格式如下:

list_name[start:end]

其中,start 为切片的起始位置(包括该位置上的元素),end 为切片的结束位置(不包括该位置上的元素)。

例如,若要访问列表 my_list 中第 2 个元素到第 4 个元素,可以使用下面的代码:

sub_list = my_list[1:4]

如果不指定起始位置,切片将从列表的第一个元素开始,如果不指定结束位置,切片将到列表的最后一个元素结束。

可以使用负数下标来从列表末尾开始计算位置。例如,要访问列表 my_list 的最后三个元素,可以使用下面的代码:

sub_list = my_list[-3:]

另外,列表切片还可以使用步长来访问列表中的元素,语法格式如下:

list_name[start:end:step]

其中,step 为步长。例如,若要访问列表 my_list 中的每第二个元素,可以使用下面的代码:

sub_list = my_list[::2]
  • 返回列表的长度

len(number)
  • 循环打印列表元素

for i in number:
    print(i)
  • 添加列表元素

number.append(10) # 在数组的末尾加入元素10
  • 删除列表元素

number.pop(1) # 删除第一个元素
number.remove(3) # 删除数组中元素为3的元素
  • 拼接两个列表

list1 = [1, 2, 3]
list2 = [4, 5, 6]
list = list1 + list2
print(list)
  • 构建二维列表

list = [[1, 2, 3],[4, 5, 6]]
print(list[0][1])

Python包含以下列表函数:

函数

作用

len(list)

返回列表元素个数

max(list)

返回列表元素最大值

min(list)

返回列表元素最小值

list(seq)

将元组转换为列表

列表中包含了以下内置方法:

方法

作用

list.append(obj)

在列表末尾添加新的对象

list.count(obj)

统计某个元素在列表中出现的次数

list.extend(seq)

在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)

list.index(obj)

从列表中找出某个值第一个匹配项的索引位置

list.insert(index, obj)

将对象插入列表

list.pop([index=-1])

移除列表中的一个元素(默认最后一个元素),并且返回该元素的值

list.remove(obj)

移除列表中某个值的第一个匹配项

list.reverse()

反向列表中元素

list.sort( key=None, reverse=False)

对原列表进行排序

list.clear()

清空列表

list.copy()

复制列表

元组(Tuple)

Python 的元组与列表类似,不同之处在于元组的元素不能修改。元组的不可变指的是元组所指向的内存中的内容不可变。元组使用小括号 ( ),列表使用方括号 [ ]

  • 新建一个包含数字的列表

tup1 = (1,2,3,4,5,6,7,8)
  • 返回元组中某下标的值

tup1[0] # 返回第一个
tup1[1:5] # 返回元组的第二个到第六个的值
  • 返回元组的长度

len(tup1)
  • 循环打印元组元素

for i in tup1:
    print(i)
  • 删除整个元组

del tup1
  • 拼接两个元组

tup1 = (1,2,3,4)
tup2 = (5,6,7,8)
tup = tup1+tup2
print(tup)
  • 构建二维元组

tup = ((1,2,3,4),(5,6,7,8))
print(tup[0][1])

Python包含以下列表函数:

函数

作用

len(tuple)

返回元组元素个数

max(tuple)

返回元组元素最大值

min(tuple)

返回元组元素最小值

tuple(iterable)

将可迭代系列转换为元组。

字典(Dictionary)

字典是另一种可变容器模型,且可存储任意类型对象。它和javascript的对象或者json对象差不多,字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,一个简单的字典实例:

person = {'name': 'jhon', 'age': 20, 'contry': 'CHINA'}

键必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的,如字符串,数字。两个重要的点需要记住:

  1. 不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住

  2. 键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行

  • 返回元组字典里的值,如果用字典里没有的键访问数据,会输出错误。

person = {'name': 'jhon', 'age': 20, 'contry': 'CHINA'}
print(person['name'])
print(person['contry'])
  • 修改/增加字典的值

person = {'name': 'jhon', 'age': 20, 'contry': 'CHINA'}
person['age'] = 21 # 键存在,则修改对应的键值
person['cash'] = 100000 # 键不存在,则增加对应的键值对
  • 删除字典元素

del person['cash'] # 删除键'cash'
  • 删除整个字典

del person

Python包含以下列表函数:

函数

作用

len(dict)

计算字典元素个数,即键的总数。

str(dict)

输出字典,可以打印的字符串表示。

type(variable)

返回输入的变量类型,如果变量是字典就返回字典类型。

字典包含了以下内置方法:

方法

作用

dict.clear()

删除字典内所有元素

dict.copy()

返回一个字典的浅复制

dict.fromkeys()

创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值

dict.get(key, default=None)

返回指定键的值,如果键不在字典中返回 default 设置的默认值

key in dict

如果键在字典dict里返回true,否则返回false

dict.items()

以列表返回一个视图对象

dict.keys()

返回一个视图对象

dict.setdefault(key, default=None)

和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default

dict.update(dict2)

把字典dict2的键/值对更新到dict里

dict.values()

返回一个视图对象

pop(key[,default])

删除字典 key(键)所对应的值,返回被删除的值。

popitem()

返回并删除字典中的最后一对键和值。

集合(Set)

集合是一个无序的不重复元素序列。可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

  • 新建一个字符串集合,打印后以字典的方式展示

s = set(("Google", "Alibaba", "Taobao", "Facebook"))
print(s)
  • 增加集合中的元素,如果元素已存在,则不进行任何操作

s.add("Twitch")
s.update({"WeChat","Tencent"})
  • 删除集合中的元素

s.remove("Tencent") # 若元素不存在会发生错误
s.discard("Tencent") # 若元素不存在不会发生错误
s.pop() # 对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除
  • 判断元素是否在集合中存在

"Youtube" in s

集合包含了以下内置方法:

方法

作用

add()

为集合添加元素

clear()

移除集合中的所有元素

copy()

拷贝一个集合

difference()

返回多个集合的差集

difference_update()

移除集合中的元素,该元素在指定的集合也存在。

discard()

删除集合中指定的元素

intersection()

返回集合的交集

intersection_update()

返回集合的交集。

isdisjoint()

判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。

issubset()

判断指定集合是否为该方法参数集合的子集。

issuperset()

判断该方法的参数集合是否为指定集合的子集

pop()

随机移除元素

remove()

移除指定元素

symmetric_difference()

返回两个集合中不重复的元素集合。

symmetric_difference_update()

移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。

union()

返回两个集合的并集

update()

给集合添加元素

深浅拷贝

我们在对变量进行赋值时,我们会用=将对象与变量连通起来,此时,我们称之为引用,引用的是对象。

a = [1, 2, 3, 4, ['a', 'b']]  # 原始对象
b = a  # 赋值,传对象的引用

a.append(5)  # 修改对象a
print('a = ', a)
print('b = ', b)

b[4].append('c')  # 修改对象b中的['a', 'b']数组对象
print('a = ', a)
print('b = ', b)

print('a的地址是: ', id(a))
print('b的地址是: ', id(b), '是否与a相等', id(a) == id(b))

运行结果

a =  [1, 2, 3, 4, ['a', 'b'], 5]
b =  [1, 2, 3, 4, ['a', 'b'], 5]
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
a的地址是:  2401854257984
b的地址是:  2401854257984 是否与a相等 True

可以看到,在修改了a的值后,b的值也会被修改了。反过来修改b的值,a的值也会跟着修改。并且a与b的地址是一模一样的,那么证明这两个变量是完全相同的,如同实体与影子(b是a的影子)。

我们对a进行一次浅拷贝,使用copy模块,例子如下:

import copy

a = [1, 2, 3, 4, ['a', 'b']]  # 原始对象
c = copy.copy(a)  # 对象拷贝,浅拷贝

a.append(5)  # 修改对象a
print('a = ', a)
print('c = ', c)

c[4].append('c')  # 修改对象b中的['a', 'b']数组对象
print('a = ', a)
print('c = ', c)

print('a的地址是: ', id(a))
print('b的地址是: ', id(c), '是否与a相等', id(a) == id(c))

运行结果

a =  [1, 2, 3, 4, ['a', 'b'], 5]
c =  [1, 2, 3, 4, ['a', 'b']]
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c =  [1, 2, 3, 4, ['a', 'b', 'c']]
a的地址是:  3252829633472
b的地址是:  3252829634432 是否与a相等 False

可以看到,在修改了a的值后,c的值却不会被修改反过来修改c的值a的值竟然会跟着修改

可以观察到a与c的地址是不一样的,可以知道a与c是两个不同的对象,但是指定的是同一个值

我们对a进行一次深拷贝,使用copy模块,例子如下:

import copy

a = [1, 2, 3, 4, ['a', 'b']]  # 原始对象
d = copy.deepcopy(a)  # 对象拷贝,深拷贝

a.append(5)  # 修改对象a
print('a = ', a)
print('d = ', d)

d[4].append('c')  # 修改对象b中的['a', 'b']数组对象
print('a = ', a)
print('d = ', d)

print('a的地址是: ', id(a))
print('b的地址是: ', id(d), '是否与a相等', id(a) == id(d))

运行结果

a =  [1, 2, 3, 4, ['a', 'b'], 5]
d =  [1, 2, 3, 4, ['a', 'b']]
a =  [1, 2, 3, 4, ['a', 'b'], 5]
d =  [1, 2, 3, 4, ['a', 'b', 'c']]
a的地址是:  2280897003456
b的地址是:  2280897002240 是否与a相等 False

可以看到,无论修改a的值还是修改b的值,它们都不会互相影响。并且a与b的地址不相同。所以我们可以知道a与d是两个完全不同的对象,值与地址都不同。

由此我们可以得出结论:

  • b = a: 赋值引用,a 和 b 都指向同一个对象。a与b相互影响

  • b = copy.copy(a): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。a不影响b,b影响a。

  • b = copy.deepcopy(a): 深拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。a与b互不影响。

字符串

创建字符串

字符串是 Python 中最常用的数据类型。我们可以使用引号('")来创建字符串。

创建字符串很简单,只要为变量分配一个值即可。例如:

String1 = 'Hello World!'
String2 = "Hello python"

字符串查找

字符串长度

调用len,该方法不仅仅用在字符串,也可以统计列表,元组的长度

name = "helloworld"
len(name)

索引

对标java的indexOf(int ch,int fromindex),索引是通过字符串下标返回该下标的字符

str[0:1]

其中str为变量,0是头下标,1是尾下标

特定字符串

调用find函数,返回首字母在匹配字符串的下标

name.find("World")

判断某字符串是否在该字符串里

in关键字,若存在则返回True

name = "helloworld"
print("world" in name)

计算子字符串在字符串中出现的次数

调用count方法

name = "helloworld"
count = name.count("l",0,len(name))
print(count)

字符串操作

删除某特定尾字符

调用rstrip,如果方法不传参则默认删除空格符

name = "helloworld;"
print(name)
count = name.rstrip(';')
print(count)

字符串类型转换

字符串类型转换为其他类型

int类型(整数类型)

str = '1'
int(str)

str = 'a'
int(str) # 强转

float类型(浮点类型)

str = '0.05'
float(str)

这里提一下浮点类型的四舍五入,可以调用round函数计算

number = 5.454245435
round(number,3)

number为传入的浮点类型,3位保留3位数

其他类型转换成字符串类型

number = 1
str(number)

正则表达式

正则表达式是一个特殊的字符序列,它能帮助人们方便的检查一个字符串是否与某种模式匹配。

可用RegExr: 学习、构建 和 测试 正则表达式 Test RegEx (regexr-cn.com)生成正则表达式

引入模块

import re

match

尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 none

re.match(pattern, string, flags=0)

形参作用如下(按传入顺序):

  • pattern:匹配的正则表达式

  • string:要匹配的字符串

  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

import re

name = "helloworld"
matcher = re.match("hello",name)
print(matcher)

匹配完成后,可用span方法在起始位置匹配

matcher.span()

search

扫描整个字符串并返回第一个成功的匹配

re.search(pattern, string, flags=0)

形参作用如下(按传入顺序):

  • pattern:匹配的正则表达式

  • string:要匹配的字符串

  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

import re

name = "helloworld"
matcher = re.search("hello",name)
print(matcher)

匹配完成后,可用group方法在返回匹配的字

matcher.group()

sub

替换字符串中的匹配项

re.sub(pattern, repl, string, count=0, flags=0)

形参作用如下(按传入顺序):

  • pattern:匹配的正则表达式

  • repl:替换的字符串,也可以是一个函数

  • string:要匹配的字符串

  • count:模式匹配后替换的最大次数,默认 0 表示替换所有的匹配

  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

import re

name = "helloworld"
print(name)
name = re.sub("hello","bello",name)
print(name)

变量

私有变量

不与其他共享,自己独享,如函数和方法的局部变量,实例变量

写的时候,在变量左边加两个下斜杆(_)即可

例如:

__a = 1
__b = "1"

变量赋值

单个变量赋值

i = 1000  # int型
j = 1000.0  # float型
name = "tom"  # 字符串型

print(i)
print(j)
print(name)

多个变量赋值

  1. 给多个变量同时赋值,变量的值相同:a = b = c = 1

  2. 为多个变量指定多个值:a, b, c = 1, 2, "tom"

类变量

class内,不在class的任何方法内,使用类变量时,将类实例化后调用

class test:
    a = "123"
    __b = 1
    
    def test01(self):
        print(self.a) # 方法调用类变量
            
    @classmethod
    def test02(cls):
        print(cls.__b) # 静态方法调用类变量

局部变量

函数内、class的方法(类方法、静态方法、实例方法)内,且变量前面没有修饰

def test01(self):
	a = 1 # 局部变量

全局变量

全局变量供全局共享,全局类和函数均可访问,达到同步作用。同时还可以被外部文件访问。

全局变量使用的时候,需要用global显示声明。 一般情况下,如果函数直接调用全局变量,不做更新的话,一般没有问题,但如果有重新赋值,又没有在函数内部使用 global声明的话, 就相当于在内部创建了一个同名的局部变量,局部变量优先级要高于全局变量。

def myfunc():
  global x
  x = "fantastic"

实例变量

class的构造方法内,使用self修饰

def __init__(self):
    self.a = 1 # 实力变量

删除变量

调用del,可删除变量

name = "helloworld"
print(name)
del(name)
print(name)

多分支选择

注意,该处只适用于python 10以上的版本

switch是“开关”的意思,它也是一种“选择”语句,但它的用法非常简单。switch是多分支选择语句。说得通俗点,多分支就是多个 if。

python在10之后加入了match-case语法,改语法的用法类似于switch,但是是比较高级的switch用法。match-case语法的使用方法如下:

def http_error(status):
    match status:
        case 400:
            return 'Bad request'
        case 401:
            return 'Unauthorized'
        case 403:
            return 'Forbidden'
        case 404:
            return 'Not found'
        case _:
            return 'Unknown status code'

可以看到,当status中输入不同的信息之后,match会进入到对应的分支上面进行匹配,从而返回对应的结果。该语法也等价于:

def http_error(status):
    if status == 400:
        return 'Bad request'
    elif status == 401:
        return 'Unauthorized'
    elif status == 403:
        return 'Forbidden'
    elif status == 404:
        return 'Not found'
    else:
        return 'Unknown status code'

case中可以使用|符号代表逻辑或,就是if上面的or,例如:

week = 7
match week:
    case 1:
        print("星期一")
    case 2:
        print("星期二")
    case 3:
        print("星期三")
    case 4:
        print("星期四")
    case 5:
        print("星期五")
    case 6 | 7:
        print("周末")

match也有很多高级用法,比如匹配序列:

a = [1, 2, 3]
match a:
    case [1]:
        print("匹配 [1]")
    case [1, obj]:
        print("匹配长度为2的列表,且列表的第一个元素是1,第二个元素不限,并用 obj 作为第二个元素的别名,若能匹配上,可以通过obj变量获取第二个元素内容", obj)
    case [1, *obj]:
        print("匹配长度大于等于1的列表,且列表第一个元素是1,后面可以有多个元素,也可以没有任何元素", obj)
    case [1, (2|3), 3]:
        print("| 代表 or;(2|3)代表列表的第二个元素要么是2,要么是3")
    case [1, (2|3) as second, 3]:
        print("和上一个一样,只不过给第二个元素绑定了一个别名:second,如果匹配上,可以通过 second 变量获取第二个元素", second)
    case [1, 2] | [1, 2, 3]:
        print('匹配 [1,2] or [1,2,3]')
    case [1, second, 3] if second == 2:
        print('带有限制条件的匹配,后面的 if 条件满足了,才会进行匹配')
    case _:
        print('_ 代表匹配其他情况,类似于 if...else.. 语句中的 else')

匹配对象:

class A(object):
    def __init__(self, x, y=None):
        self.x = x
        self.y = y
a = A(1, 1)
b = A(2, 2)
c = A(3)  # 使用了默认参数
obj = [a, b, c]
for i in obj:
    match i:
        case A(x=1, y=1):  # 此处不能直接写实例化的对象,要写 类名(参数,..)
            print('匹配实例化类时,参数x=1, y=1 的对象')
        case A(x=3):
            print('匹配实例化类时,参数x=3,y使用了默认值的对象')
        case A(x=first, y=second):
            print("匹配参数为任意值的实例化对象,first,second两个变量,可以方便的获取对象 x,y 属性实际存储的值",first, second)

匹配字典:

a = {'name': 'wang', "age": 22}
b = {'name': b'zhang', 'age': "33"}
c = {'name': b'zhao', 'age': 23}
ls = [a, b, c]
for i in ls:
    match i:
        case {"name": name, 'age': int(age)}:  # int(age) 代表匹配 age 字段是整数类型的值,name 字段没有规定,所以任意类型都会匹配
            print(f"匹配 age 是整数类型的:{name},{age}")
        case {"name": name, "age": str(age)}:
            print(f'匹配 age 是字符串类型的:{name},{age}')

面向对象

用来描述具有相同的属性和方法的对象的集合。

类中双下划线函数的作用

使用demo类

class A:

    def __init__(self):
        print("我调用了init方法")

    def __new__(cls):
        print("我调用了new方法")
        return super().__new__(cls)

    def method(self):
        print("执行function")

    def __del__(self):
        print("我调用了del方法")


if __name__ == '__main__':
    a = A()
    a.method()

__init__

负责进行对象的初始化,它是python中的构造方法

demo类中执行到__init__输出的是

我调用了init方法

__new__

负责创建类实例的静态方法,__new__的执行顺序优先于__init__

依照Python官方文档的说法,__new__方法主要是当用户继承一些不可变的class时(比如int, str, tuple), 提供给用户一个自定义这些类的实例化过程的途径。

__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供

__new__必须要有返回值,返回实例化出来的实例,这点在实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例

demo类中执行到__new__输出的是

我调用了new方法
我调用了init方法

__del__

负责销毁实例化对象,在编写程序时,如果之前创建的类实例化对象后续不再使用,最好在适当位置手动将其销毁,释放其占用的内存空间。

大多数情况下,Python 开发者不需要手动进行垃圾回收,因为 Python 有自动的垃圾回收机制,能自动将不需要使用的实例对象进行销毁。

无论是手动销毁,还是 Python垃圾回收机制自动销毁,都会调用 __del__方法。

demo类中执行到__del__输出的是

我调用了new方法
我调用了init方法
执行function
我调用了del方法

创建类

使用 class 语句来创建一个新类,class 之后为类的名称并以冒号结尾:

class Test01:
    """创建类"""
    a = "1" # 类变量

构造方法

当创建了这个类的实例时就会调用该方法

def __init__(self):
    pass

类的方法

类方法

def test01(self):
    pass

私有方法

def __test01(self):
    pass

抽象方法(不需要实例化对象直接调用,像调用类变量,例如:Test01.test01()

@classmethod
def test01(cls):
    pass

实例化对象

实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式。

test01 = Test01() # 创建一个名为test01对象
test02 = Test01() # 创建一个名为test02对象

访问属性

访问方法

test01.test01() # 调用类方法

调用类变量

test01.a

在模块中,有一个__init__.py的文件,这个文件说明该文件夹为一个,该文件夹的名字为包名

__init__.py可以指定某个包下导入的类,例如,在Utils包中的__init__文件写入:

from .DataTimeUtils import DataTimeUtils
from .YAMLReader import YAMLReader

__all__ = ["DataTimeUtils",
           "YAMLReader",]

在其他类中导入时使用from Utils import *即可导入__init__文件中指定的所有类

from Utils import *
print(DataTimeUtils.getDay(0))

也可以指定某一个特定的类

from Utils import DataTimeUtils
print(DataTimeUtils.getDay(0))

该办法可以让导入更加容易,并且一定程度封闭该包下的类,但是该方法实测过会损耗性能

__init__.py默认不写时,可导入该包下的类,用from Utils.DataTimeUtils import DataTimeUtils即可

引用类

from .... import ....

引用类时,使用from Test.Test02 import Test02,具体是from 包名.类名 import 类名,调用时,直接实例化即可,例:

from Utils.DataTimeUtils import DataTimeUtils
dtu = DataTimeUtils()
dtu.getDay(0)

当一个py文件中没有类时(面向过程编程),使用from Test.Test02 import function,具体是from 包名.py文件名 import 方法名,想要使用该方法时,直接调用即可,例:

from Test.Test02 import function
function()

import ....

引用类时,使用import Utils.DataTimeUtils,具体是import 包名.模块名(py文件名),调用时,需要完整写出包名.模块名.类名()去实例化一个类,例:

import Utils.DataTimeUtils
dtu = Utils.DataTimeUtils.DataTimeUtils()
day = dtu.getDay(0)

当一个py文件中没有类时(面向过程编程),使用import Test02,具体是import 包名.模块名(py文件名),想要使用该模块中的方法时,使用模块名.方法名()即可调用该方法,例:

import Test02
Test02.function()

动态导入

动态导入指的是在运行时加载模块。这可以用于延迟加载模块,或者根据需要加载模块。

最常见的方法是使用 importlib 模块的 import_module 函数。例如,你可以这样做:

import importlib

def get_module(name):
  return importlib.import_module(name)

math = get_module('math')
print(math.add(1, 2)) # 3

你也可以使用 __import__ 内置函数来实现动态导入:

def get_module(name):
  return __import__(name)

math = get_module('math')
print(math.add(1, 2)) # 3

注意,这些方法只能用于导入模块,而不能用于导入模块中的特定对象。要动态导入模块中的特定对象,可以使用 getattr 函数:

def get_function(module_name, function_name):
  module = __import__(module_name)
  return getattr(module, function_name)

add = get_function('math', 'add')
print(add(1, 2)) # 3

继承

通过继承创建的新类称为子类派生类,被继承的类称为基类父类超类

语法:

class base:
    """父类"""
    pass

class Test01(base):
    """子类"""
    pass

一个类可以继承多个类,称为多继承,使用时尽量单继承

语法:

class base01:
    """父类1"""
    pass

class base02:
    """父类2"""
    pass

class Test01(base01,base02):
    """子类"""
    pass

调用

子类可以调用父类的方法与类变量,并且可以调用祖先(父类的父类)的方法与类变量

class base:
    a = "1"

    def base_test01(self):
        print("test")

class Test01(base):

    def test01(self):
        print(self.a)
        print(self.base_test01())

重写父类方法

子类可以重写父类的方法

class base:
    a = "1"

    def base_test01(self):
        print("test")

class Test01(base):

    def base_test01(self):
        print("test01")

继承实现接口

在python中,是没有interface的,实现接口,可以使用abc模块实现,例

import abc

class base(metaclass = abc.ABCMeta):

    @abc.abstractmethod
    def base_test01(self):
        pass

class Test01(base):

    def base_test01(self):
        print("test")

@abc.abstractmethod定义该方法为抽象方法,metaclass = abc.ABCMeta定义该类为抽象基类

若继承的接口类没有实现base_test01,则报错:

TypeError: Can't instantiate abstract class Test01 with abstract methods base_test01

在继承抽象类的过程中,应该尽量避免多继承;而在继承接口的时候,反而鼓励多继承接口。

在抽象类中,可以对一些抽象方法做出基础实现;而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现。

文件操作

Open

如果想用python读取文件,第一步要用open函数打开文件。open()是python的内置函数,它会返回一个文件对象,这个文件对象拥有read、readline、write、close等方法。

open函数有两个参数:

open('file','mode')

其中,file为需要打开的文件路径,mode为打开文件的模式,如只读、追加、写入等

mode常用的模式:

  • r:表示文件只能读取

  • w:表示文件只能写入,若文件不存在会创建一个

  • a:表示打开文件,在原有内容的基础上追加内容,在末尾写入

  • w+:表示可以对文件进行读写双重操作

mode参数可以省略不填,默认模式为r;mode参数还可以指定以什么样的编码方式读写文本,默认情况下open是以文本形式打开文件的,比如上面的四种mode模式。

当你需要以字节(二进制)形式读写文件时,只需要在mode参数中追加'b'即可:

  • rb:以二进制格式打开一个文件,用于只读

  • wb:以二进制格式打开一个文件,用于只写

  • ab:以二进制格式打开一个文件,用于追加

  • wb+:以二进制格式打开一个文件,用于读写

with关键字

在打开文件时,很多人通常直接用open('file')。在文件读写时可以使用 with 关键字。优点是当子句体结束后文件会正确关闭,即使在某个时刻引发了异常。

with open('workfile') as f:
    for i in range(0,3):
    	read_data = f.write("test")
	f.closed

close

打开文件并处理完毕后,需要关闭文件,这里用到close方法。

f.close() 用来关闭文件并立即释放它使用的所有系统资源。如果没有显式地关闭文件,Python的垃圾回收器最终将销毁该对象并关闭打开的文件,但这个文件可能会保持打开状态一段时间。

应该要养成使用close()的习惯。使用方法很简单:

f = open(file) # 打开文件
f.close() # 关闭文件

read

当使用open函数打开文件后,就可以使用该文件对象的各种方法了,read就是其中一种。

read()会读取一些数据并将其作为字符串(在文本模式下)或字节对象(在二进制模式下)返回。

read方法有一个参数:

f.read(size) # f为文件对象

参数size(可选)为数字,表示从已打开文件中读取的字节计数,默认情况下为读取全部。

假设有一个文件sample1.txt,内容如下:

This is python big data analysis!

现在读取该文件:

with  open('sample1.txt') as f:
content = f.read()
    print(content)
    f.close()

readline

readline方法从文件中读取整行,包括换行符'\n'。

换行符(\n)留在字符串的末尾,如果文件不以换行符结尾,则在文件的最后一行省略,这使得返回值明确无误。

如果 f.readline() 返回一个空的字符串,则表示已经到达了文件末尾,而空行使用 '\n' 表示,该字符串只包含一个换行符。

f.readline()有一个参数:

f.readline(size)

参数size表示从文件读取的字节数。

假设有一个文件sample2.txt,共三行,内容如下:

hello,my friends!
This is python big data analysis,
let's study.

用readline函数读取该文件:

with open('a.txt') as f:
    print(f.readline())
    print(f.readline(5))
    f.close()

readline方法会记住上一个readline函数读取的位置,接着读取下一行。

readlines

readlines方法和readline方法长得像,但功能不一样,前面说过readline方法只读取一行,readlines方法则是读取所有行,返回的是所有行组成的列表。

readlines方法没有参数,使用更加简单。依旧以sample2.txt为例:

with open('a.txt') as f:
    print(f.readlines())
    f.close()

write

write方法顾名思义,就是将字符串写入到文件里。

它只有一个参数:

f.write([str]) # f为文件对象

参数[str]代表要写入的字符串

使用起来也很简单,比如将下面字符串(注意里面的转行符'\n')

'hello,my friends!\nthis is python big data analysis'

写入到文件sample3.txt里。

with open('sample3.txt','w') as f:
    f.write('hello,my friends!\nthis is python big data analysis')
    f.close()

pathlib

pathlib提供了一种面向对象的方式来操作文件系统路径。它的目标是提供一种更简洁、更具可读性的方式来处理文件和目录。

在Python 2.6版本引入了pathlib模块,并在Python 3中进一步改进。使用 pathlib,你可以通过创建 Path 对象来操作文件和目录的路径,并执行各种操作,如检查路径是否存在、创建新目录、遍历目录等。

pathlib 提供了一组丰富的方法和属性,使得路径操作更加方便和直观。你可以使用Path类的实例来代表文件路径或目录路径,然后通过调用相应的方法来执行所需的操作。这种面向对象的风格使得代码更易于理解和维护。

pathlib官方文档:pathlib-文件系统路径操作

引入

import pathlib

快速入门

以下是一个pathlib的快速入门例子:

from pathlib import Path

# 创建一个Path对象
file_path = Path("/path/to/file.txt")

# 检查路径是否存在
if file_path.exists():
    print("文件存在")

# 获取文件名
print("文件名:", file_path.name)

# 获取文件后缀
print("文件后缀:", file_path.suffix)

# 获取文件大小
print("文件大小:", file_path.stat().st_size)

# 遍历目录中的文件
dir_path = Path("/path/to/directory")
for file in dir_path.iterdir():
    print(file.name)

新建Path对象

为了使用pathlib,我们需要创建一个Path对象。

from pathlib import Path

# 创建一个Path对象
path = Path("/path/to/file.txt")

# 也可以像这样拼接起来
path = Path("D:\\","My_Document","project")

路径拼接

上面我们在新建Path的时候执行了一次拼接,除了创建Path类对路径进行拼接外,我们也可以使用/符号进行路径拼接。

这里面的/符号,并不是传统意义上字符串路径上的斜杠或者反斜杠符号,也不是python中的除号,它代表的是一个层级,表示文件之间的层级关系。

例如:

path = Path("/user/file/","file1") # 新建Path对象对路径进行拼接
print(path)
path = path / "test.txt" # 使用/对路径进行拼接
print(path)

输出:

/user/file/file1
/user/file/file1/test.txt

获取路径

新建path对象后,我们可以获取路径的不同部分、或不同字段等内容,比如:

from pathlib import Path

# 创建一个Path对象
path = Path("/path/to/file.txt")

path.name  # 返回文件名+文件后缀
path.stem  # 返回文件名
path.suffix  # 返回文件后缀
path.suffixes  # 返回文件后缀列表
path.root  # 返回根目录
path.parts  # 返回文件路径的每一部分
path.anchor  # 返回根目录
path.parent  # 返回父级目录
path.parents  # 返回所有上级目录的列表

也可以获取系统的一些信息,比如:

from pathlib import Path

Path.cwd() # 返回当前python文件的文件夹
Path.home() # 返回系统用户文件夹

执行判断

  • Path().exists(): 判断该文件或文件夹是否存在

  • Path().is_dir(),判断 Path 是否是一个文件夹

  • Path().is_file(),判断 Path 是否是一个文件

例子:

from pathlib import Path

path = Path("/path/to/file.txt")

if path.exists():
	if path.is_file():
		print("路径存在,为文件")
	elif path.is_dir():
		print("路径存在,为文件夹")
else:
	print("不存在该文件/文件夹")

创建/删除操作

  • Path().mkdir(): 创建文件夹

  • Path().rmdir(): 删除文件夹,注意,文件夹必须为空

  • Path().unlink(): 删除文件

例子:

from pathlib import Path

path = Path("/path/to/file.txt")

# 创建文件夹函数
if path.exists():  # 如果已经存在,则跳过并提示
    print("文件夹已存在,无需创建")
else:
    path.mkdir()  # 创建文件夹

# 删除文件夹
if path.exists():  # 如果存在,则删除文件夹
    path.rmdir()
else:
    print("文件夹不存在,无需删除")

# 删除文件
if path.exists():  # 如果存在,则删除文件
    path.unlink()
else:
    print("文件不存在,无需删除")

文件读写

pathlib支持文件读写,Path().open()等同于open,可以用with打开。以下是常用的文件读写api:

  • Path().open(): 默认以r格式打开文件

  • Path().read_bytes(): 打开文件,以字节流格式读取文件内容,等同open操作文件的rb格式,在读取文件后会自动关闭文件流

  • Path().read_text(): 打开文件,以 str 格式读取文件内容,等同open操作文件的r格式,在读取文件后会自动关闭文件流

  • Path().write_bytes(): 对文件进行写操作,等同open操作文件的wb格式,在写入文件后会自动关闭文件流

  • Path().write_text(): 对文件进行写操作,等同open操作文件的w格式,在写入文件后会自动关闭文件流

例子:

from pathlib import Path

path = Path("/path/to/file.txt")

with path.open('w') as f:  # 创建并打开文件
	f.write('aaaabbbbcccc')  # 写入内容
file_text = path.read_text()  # 读取内容
print(f"读取的文件内容为:{file_text}")

pathlib替代os常用操作

pathlib可以替代os的一些函数,详细对比如下:

pathlib函数

os函数

功能描述

Path().resolve()

os.path.abspath()

获取文件绝对路径

Path().chmod()

os.chmod()

修改文件权限和时间戳

Path().mkdir()

os.mkdir()

创建文件夹

Path().rename()

os.rename()

重命名文件或文件夹,如果路径不同,会移动该文件夹并重新命名

Path().replace()

os.replace()

重命名文件或文件夹,如果路径不同,会移动该文件夹并重新命名,如果存在,则替换现有目标

Path().rmdir()

os.rmdir()

删除文件夹,文件夹必须为空

Path().unlink()

os.remove()

删除文件

Path.cwd()

os.getcwd()

返回当前python文件的文件夹

Path().exists()

os.path.exists()

判断该文件或文件夹是否存在

Path.home()

os.path.expanduser()

返回系统用户文件夹

Path().is_dir()

os.path.isdir()

判断是否为文件夹

Path().is_file()

os.path.isfile()

判断是否为文件

Path().is_symlink()

os.path.islink()

判断是否为符号链接

Path().stat()

os.stat()

获取文件属性

PurePath().is_absolute()

os.path.isabs()

判断是否为绝对路径

PurePath().joinpath()

os.path.join()

连接目录与文件名或目录

PurePath().name

os.path.basename()

获取文件名

PurePath().parent

os.path.dirname()

获取文件路径

Path.samefile()

os.path.samefile()

判断两个路径是否相同

PurePath().suffix

os.path.splitext()

分离文件名和扩展名

shutil

shutil 模块提供了一组高级文件和目录操作函数,它与os模块形成互补的关系。os主要提供了文件或文件夹的新建、删除、查看等方法,还提供了对文件以及目录的路径操作。shutil模块提供了移动、复制、 压缩、解压等操作,恰好与os互补。

引入shutil,我们需要这么做:

import shutil

以下是常用的几种API:

方法

作用

shutil.copy(src, dst)

复制单个文件

shutil.copy2(src, dst)

shutil.copy() 类似,但保留文件的元数据(例如访问时间)

shutil.copytree(src, dst)

复制整个目录树

shutil.move(src, dst)

移动或重命名文件或目录

shutil.rmtree(path)

递归删除目录树

shutil.make_archive(base_name, format, root_dir)

创建文件归档(例如压缩文件)。

shutil.unpack_archive(filename, extract_dir)

解压缩文件归档

下面是一些示例。

  • 复制单个文件:

import shutil

shutil.copy("file1.txt", "file2.txt")
  • 复制目录树:

import shutil

shutil.copytree("folder1", "folder2")
  • 移动文件或目录:

import shutil

shutil.move("file.txt", "new_folder/file.txt")
  • 创建压缩文件:

import shutil

shutil.make_archive("myfiles", "zip", "myfiles")
  • 解压缩文件:

import shutil

shutil.unpack_archive("myfiles.zip", "extracted_files")
  • 删除目录树

import shutil

shutil.rmtree("folder_to_delete")

请注意,在使用 shutil 模块的函数时,请谨慎操作,因为一些函数(如 rmtree())可能会删除文件或目录。

相对路径解决办法

python操作文件的时候,相对路径是把运行的当前的.py文件作为基准的

假设当前的目录为:

  • Test

    • test.py

  • image

    • test.png

  • main.py

当运行main.py操作test.png这个文件的时候,相对路径则是./image/test.png

但是,当运行test.py操作test.png这个文件的时候,相对路径则是../image/test.png

因为这个,可能在编写代码,进行代码单元测试时可能正常,结果到运行整个项目的时候,就报错了,但是发现错误时,需要将代码里的所有的路径全部改一遍,如果代码量多,则增加工作量,显然不是明智之举。而在开发的时候,由于思维惯性,不可避免会发生这种错误。以下提供解决办法

默认

在开发的时候根据启动类,调整开发思维,将所有的相对路径以启动类为基准进行编写

该方法强烈不推荐,对某个模块进行测试的时候会非常麻烦

动态获取绝对路径

思路:

  1. 在父类中获取改py文件的绝对路径

  2. 通过字符串搜索项目所在根目录,返回路径

  3. 将路径定义为类变量(或全局变量),子类应用即可

import os

abs_path = os.path.abspath(os.path.dirname(__file__)) # 返回当前py文件下的绝对路径
root_path = abs_path[0:abs_path.find("Test")] # 返回根目录
print(root_path) # 子类用self.root_path即可

动态切换当前工作目录

思路

  1. 动态获取当前绝对路径abs_path

  2. 每个类调用os.chdir(abs_path),动态切换当前工作目录到该路径中

abs_path = os.path.abspath(os.path.dirname(__file__))
os.chdir(abs_path)

OS

在 Python 中,os 模块是用于操作操作系统相关功能的模块。该模块提供了一组与操作系统交互的函数和方法,包括文件和目录操作,进程管理,环境变量管理等等。

以下是 os 模块的一些常用功能:

  • 文件和目录操作:os 模块提供了许多用于文件和目录操作的函数和方法,如创建、删除、移动、复制、重命名文件和目录等。

  • 进程管理:os 模块提供了一些函数和方法,用于启动新的进程,管理当前进程和其他进程,如获取进程 ID、等待进程结束等。

  • 环境变量管理:os 模块提供了一些函数和方法,用于读取、设置、删除系统环境变量。

  • 文件描述符操作:os 模块提供了一些函数和方法,用于打开文件、读写文件、关闭文件、获取文件描述符等。

  • 杂项:os 模块还提供了一些其他功能,如获取系统信息、判断文件是否存在、获取文件大小、获取文件权限等。

引入

import os

执行shell命令

os.system()是一个可以在 Python 中执行 shell 命令的函数。它接收一个字符串参数,该字符串参数是需要执行的 shell 命令,然后在终端中执行该命令并返回执行结果。

下面是一个使用 os.system() 函数执行 shell 命令的示例:

import os

# 执行一个 shell 命令并获取执行结果
result = os.system("ls -l")
print(result)

os.system() 函数的使用相对简单,可以方便地执行一些 shell 命令。但是需要注意的是,该函数执行的是一个新的 shell 进程,因此可能会导致一些性能上的问题。如果需要更高效地执行 shell 命令,可以考虑使用subprocess模块中的函数。

文件操作

删除文件

os.remove(path)  # path是文件的路径,如果这个路径是一个文件夹,则会抛出OSError的错误,这时需用用rmdir()来删除
os.rmdir(path)  # path是文件夹路径,注意文件夹需要时空的才能被删除
os.unlink('F:\新建文本文档.txt')  # unlink的功能和remove一样是删除一个文件,但是删除一个删除一个正在使用的文件会报错。

判断是否存在该文件

使用os.path.exists判断某个文件是否存在

is_exists = os.path.exists("test.png")
print(is_exists)

创建文件夹

os.mkdir('d:\hello') # 在一级目录中创建
os.makedirs('d:\hello\world\123') # 创建多级目录

获取某文件的绝对路径

abs_path = os.path.abspath("test.png") # 返回test.png的绝对路径
py_abs_path = os.path.abspath(os.path.dirname(__file__)) # 返回当前py文件下的绝对路径
print(abs_path)
print(py_abs_path)

路径拼接

last_path = os.path.join("D:/Test", "test.png")
print(last_path)

检索目录下的文件

os提供了三个api来检索当下目录的文件,分别是os.listdiros.walkos.scandir

os.listdir非常简单粗暴,它返回path目录下的文件夹和文件,但不包含子文件夹里的文件夹和文件,并按照目录树结构的排序输出结果,即深度优先。例如:

import os

# 列出当前工作目录中的所有文件和子目录
files = os.listdir()

# 列出指定目录中的所有文件和子目录
files = os.listdir('/path/to/directory')

os.walk()通过“自上而下”(先遍历当前目录,后遍历子目录)或“自下而上”(先遍历子目录,后遍历当前目录)来遍历目录,生成目录树中的文件夹名和文件名。它可传输的形参如下:

  • top:根目录下的每一个文件夹(包含它自己)

  • topdown:可选,为True时,则自上而下,而为False时,则自下而上,默认True

  • onerror:可选,是一个函数,OSError实例

  • followlinks:可选,通过软链接访问目录

它同时返回三个结果:

  • root:根目录

  • dirs:根目录包含的子文件夹

  • files:根目录包含的子文件

它使用的例子如下:

import os

path = 'd:\hello'
# 遍历指定目录下所有文件和子文件夹文件
for root,dirs,files in os.walk(path):
    print(files)

如果该目录下面还有目录,则会继续搜索文件。如果只想搜索当前目录下的文件,可以在末尾加break只浏览一层目录:

import os

path = 'd:\hello'
# 遍历指定目录下所有文件
for root,dirs,files in os.walk(path):
    print(files)
    break

如果遍历文件夹下面所有的文件(包含子文件夹),在遍历files的时候加入root即可,这是因为os.walk会从外逐层遍历文件,root会记录遍历file的路径。

import os
from pathlib import Path

path = 'd:\hello'
# 遍历指定目录下所有文件
for root,dirs,files in os.walk(path):
    for file in files:
        print(Path(root, file))

os.scandir返回path目录树中对应的os.DirEntry对象的迭代器(文件夹或文件),不包含子文件夹里的文件夹和文件,但运行效率比os.walk高。Python官方推荐使用os.scandir来遍历目录树。

它的用法基本如下:

import os

with os.scandir(path) as entries:
    for entry in entries:
        # 处理 entry

entries中的entry是一个DirEntry对象,表示遍历到的每一个文件或目录。DirEntry对象有以下属性和方法:

  • name: 表示文件或目录的名称。

  • path: 表示文件或目录的完整路径。

  • is_file(): 返回一个布尔值,表示当前对象是否为文件。

  • is_dir(): 返回一个布尔值,表示当前对象是否为目录。

  • stat(): 返回一个os.stat_result对象,包含了文件或目录的详细信息,如大小、创建时间等。

使用scandir函数遍历目录时,会自动管理目录资源的关闭和释放,因此建议使用with语句来打开目录。此外,scandir函数返回的是一个生成器对象,因此可以在遍历时逐个处理文件或目录,而不必将所有文件或目录都读入内存,因此在处理大型目录时,使用scandir函数可以提高程序的性能。

改变当前工作目录到指定的路径

os.chdir(path)

进程管理

在 Python 的 os 模块中,有一些函数可以用于进程管理。以下是一些常用的函数:

  • os.fork(): 创建一个新的进程,新进程是原进程的一个副本,但是在新进程中返回值是 0,而在原进程中则是新进程的 PID。

import os
import time

pid = os.fork()
if pid == 0:
    # 子进程
    print("Child process %d" % os.getpid())
    time.sleep(1)
else:
    # 父进程
    print("Parent process %d" % os.getpid())
    os.waitpid(pid, 0)
    print("Child process %d has terminated" % pid)
  • os.exec(): 在当前进程中执行一个新的程序,该程序替换当前进程。exec 函数有多个变种,如 os.execvp()、os.execvpe()、os.execve() 等。

import os

os.execvp('ls', ['ls', '-l'])
print("This line will not be executed")
  • os.waitpid(pid, options): 等待指定 PID 的进程结束,返回值是子进程的 PID 和退出状态信息。

import os
import time

pid = os.fork()
if pid == 0:
    # 子进程
    print("Child process %d" % os.getpid())
    time.sleep(1)
    exit(123)
else:
    # 父进程
    print("Parent process %d" % os.getpid())
    pid, status = os.waitpid(pid, 0)
    print("Child process %d has terminated with status %d" % (pid, status))
  • os.kill(pid, signal): 向指定 PID 的进程发送信号,signal 参数指定了信号类型,如 SIGTERM、SIGKILL 等。

import os
import time

# 创建一个新进程
pid = os.fork()
if pid == 0:
    # 子进程
    print("Child process %d" % os.getpid())
    while True:
        print("Child process is running")
        time.sleep(1)
else:
    # 父进程
    print("Parent process %d" % os.getpid())
    # 等待一段时间后向子进程发送 SIGTERM 信号
    time.sleep(5)
    os.kill(pid, 15)  # 发送 SIGTERM 信号
    print("Sent SIGTERM signal to child process %d" % pid)

环境变量管理

在 Python 的 os 模块中,可以使用以下常用函数来管理环境变量:

  1. os.environ:获取当前进程的所有环境变量,返回一个字典。

  2. os.getenv:获取指定名称的环境变量,如果不存在则返回 None。

  3. os.putenv:设置指定名称的环境变量。

  4. os.unsetenv:删除指定名称的环境变量。

下面是一些示例代码:

  • 获取所有环境变量并打印出来:

import os

for k, v in os.environ.items():
    print("%s=%s" % (k, v))
  • 获取指定名称的环境变量并打印出来:

import os

value = os.getenv("PATH")
if value:
    print("PATH=%s" % value)
else:
    print("PATH environment variable not set.")
  • 设置一个新的环境变量并打印出来:

import os

os.putenv("MY_VAR", "Hello World")
value = os.getenv("MY_VAR")
print("MY_VAR=%s" % value)
  • 删除一个环境变量并打印出来:

import os

os.environ["MY_VAR"] = "Hello World"
value = os.getenv("MY_VAR")
print("MY_VAR=%s" % value)

os.unsetenv("MY_VAR")
value = os.getenv("MY_VAR")
if value:
    print("MY_VAR=%s" % value)
else:
    print("MY_VAR environment variable not set.")

语法糖

Python 中有许多语法糖,这些语法糖可以让你的代码更简洁、易读。以下是一些常用的语法糖:

列表推导式:这是一种简洁的创建列表的方式,可以在一行代码中完成循环、过滤和转换的操作。示例:

# 列表推导式:首先用[]盖住,for前面为循环内部的方法,之后append在list里面,结果放左边
list = [random.randint(0,100) for i in range(10)]
"""
该方法等价于
list = []
for i in range(10):
    list.append(random.ranint(0,100))
"""
print(list)

字典推导式:这是一种简洁的创建字典的方式,可以在一行代码中完成循环、过滤和转换的操作。示例:

# 集合推导式:首先用{}盖住,for前面为循环内部的方法,之后add在list里面,写法与列表推导式一致
dic_list = {random.randint(0,100) for i in range(10)}
"""
该方法等价于
dic_list = []
for i in range(10):
    dic_list.add(random.ranint(0,100))
"""
print(dic_list)

集合推导式:这是一种简洁的创建集合的方式,可以在一行代码中完成循环、过滤和转换的操作。示例:

# 字典推导式:首先用{}盖住,for前面为循环内部的方法,之后add在dic里面,写法与集合推导式几乎一致,只是多了个索引加个冒号
dic = {i:random.randint(0,100) for i in range(10)} 
print(dic)

元组拆包:这是一种简洁的将元组中的元素赋值给变量的方式,可以在一行代码中完成多个赋值的操作。示例:

x, y = (1, 2)
print(x) # 1
print(y) # 2

三元表达式:这是一种简洁的条件表达式,它通常比if有更强的性能,可以在一行代码中完成条件判断和赋值的操作。示例:

x = 10
y = 20
z = 30
f = 50
maxvalue = x if x > y else y # 三元表达式,判断的结果放左边
"""
该方法等价于
maxvalue = 0
if x > y:
    maxvalue = x
else:
    maxvalue = y
"""
# 也可以像这样子套娃
maxvalue_2 = x if x > y and x > z and x > f else y if y > x and y > z and y > f else z if z > x and z > y and z > f else f
print(maxvalue)
print(maxvalue_2)

# 也可以不加if,用`and`和`or`输出结果
i = 1
j = i == 1 and "是" or "否"
print(j)

# 这种方式也可以套娃
i = 3
j = i == 1 and "是" or i == 2 and "是" or i == 3 and "是" or "否"
print(j)

try-else语句:用于在try语句成功后执行特定代码。

try:
    print("运行i = 2/1,此时try运行成功")
    i = 2/1
    # print("运行i = 2/0,此时try运行失败")
    # i = 2/0
except:
    print("当try运行失败,except会被运行,此时else是不会被运行的")
else:
    print("当try成功运行后,else才会被运行")

with语句:这是一种简洁的打开和关闭文件、锁定资源等操作的方式,可以避免手动关闭文件或释放资源导致的错误。示例:

with open("file.txt") as f:
    data = f.read()
    print(data)

lambda表达式:这是一种简洁的创建匿名函数的方式,可以在一行代码中完成函数定义和调用的操作。示例:

add = lambda x, y: x + y
result = add(1, 2)
print(result)

函数参数默认值:这是一种简洁的为函数参数设置默认值的方式,可以避免额外的判断和错误。示例:

def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("John")
greet("Jane", "Hi")

内置函数

Python 有很多内置函数,这些函数可以直接使用,不需要导入额外的模块。常用的内置函数包括:

  • print():用于输出信息到控制台。

print("hello world")
  • len():用于返回序列(如字符串、列表、元组)的长度。

list1 = [1, 2, 3]
print(len(list1))
  • type():用于返回对象的类型。

list1 = [1, 2, 3]
print(type(list1))
  • int()float()str():用于将其他类型转换为整数、浮点数、字符串。

string = '1'
print(int(string))
integer = 1
print(float(integer))
print(str(integer))
  • list():将其他类型转换为列表。

tup = (1, 2, 4)
print(list(tup))
  • min()max():用于返回序列中的最小/最大值。

list1 = [1, 2, 3]
print(min(list1))
print(max(list1))
  • all():用于判断列表(元组也行)中的所有元素是否都为 True,如果是返回 True,否则返回 False。

>>> all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
>>> all(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
False
>>> all([0, 1,2, 3])          # 列表list,存在一个为0的元素
False
   
>>> all(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
True
>>> all(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
False
>>> all((0, 1, 2, 3))          # 元组tuple,存在一个为0的元素
False
   
>>> all([])             # 空列表
True
>>> all(())             # 空元组
True
  • any():用于判断列表(元组也行)中的所有元素是否包含True,如果有一个为 True,则返回 True,如果都是False,则放回False。

>>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
 
>>> any(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
True
 
>>> any([0, '', False])        # 列表list,元素全为0,'',false
False
 
>>> any(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
True
 
>>> any(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
True
 
>>> any((0, '', False))        # 元组tuple,元素全为0,'',false
False
  
>>> any([]) # 空列表
False
 
>>> any(()) # 空元组
False
  • round():用于对浮点数进行四舍五入。

number = 3.1415926535
print(round(number, 3))
  • sum():用于对序列中的所有元素求和。

list1 = [1, 2, 3]
print(sum(list1))
  • sorted():用于对序列进行排序。

list1 = [1, 6, 3, 8, 5]
print(sorted(list1))
  • abs():用于返回数字的绝对值。

num = -1
print(abs(num))
num = 1
print(abs(num))
  • range():用于生成一个整数序列。

print(range(3))
# range(0, 3)
print(list(range(3))) # 需要转化成list才可以看得更加直观
# [0, 1, 2]
print(list(range(1, 3)))
# [1, 2]
文章作者: Vsoapmac
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 soap的会员制餐厅
python python基础
喜欢就支持一下吧