python语言特性代码片段总结


本文内容比较零散,是笔者在学习python过程中遇到的一些能展示python语言特点的代码片段。其中不乏笔者工作中常用的小功能,比如视频中取图片,数据分析pandas的应用等。随着笔者对python语言的了解,相信后续对python 特性的整理以及提供的代码片段会更具有代表性和实用性。

三元表达式

类似与c++中的

ans = x>y ? x : y

在python中是

ans = x if x>y else y

命令行进度条(tdqm)

from tqdm import tqdm

在命令行中执行比较耗时的循环操作时,如果知道具体的循环次数,则可以使用命令行进度条tdqm。
在for循环外

total = len(sorted(os.scandir(path),key=lambda x: x.name))
status_bar = tqdm(os.scandir(path), total=total,desc="descrption")

其中,第一个参数是迭代器,total参数代表迭代次数,desc参数代表显示的描述。
在循环中,使用

status_bar.update(1)

参数处理

import argparse

Python脚本更加简洁的一个原因,不需要写复杂判断,使用argparse模块,可以实现运行参数的可配置,甚至使用子参数调用不同的子模块,及其子模块参数。
普通参数

parser = argparse.ArgumentParser()
parser.add_argument("-v","--verbosity",help = "help")
args = parser.parse_args()
print(args)

输入:

python parsse.py -v aa

输出:

Namespace(verbosity='aa')

子参数

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# 增加两个子参数train 和 test
train = subparsers.add_parser("train",
                            help="train",
                            description="description")
train.add_argument("-t1","--trainparse1",help="trainparse1 help",default="t1default")
train.add_argument("-t2","--trainparse2",help="trainparse2 help",type=int,required=True)
train.set_defaults(func = run_train)   # run_train是一个前面定义的函数

test = subparsers.add_parser("test")
test.add_argument("-t3","--testparse3",help="testparse3")
test.add_argument("-t4","--testparse4",help="testparse4",type=float) 
module = import_module("scripts.test")
modulenew = getattr(module,"Test")
testobject = modulenew(100)  #新建一个类对象, 使用类对象调用类函数
test.set_defaults(func = testobject.test)  #类似于声明, 并不真正执行代码

args = parser.parse_args()
args.func(args) # 脚本调用真正发生在这个地方
# print(args)

run_train函数

def run_train(args):
    print("run_train")
    print(args.trainparse1)
    print(args.trainparse2)

Test类脚本调用

class Test():
    """Description."""
    def __init__(self, args):
        pass

    def test(self, arguments):
        print("test:",arguments)

输入1:

python parsse.py  train -t2 100

输出1:

run_train:
t1: t1default
t2: 100

输入2:

python parsse.py test -t3 1000 -t4 2000

输出2:

Test.test:
t3: 1000
t4: 2000.0

矛盾选项
使用add_mutually_exclusive_group可以添加矛盾的选择。

parser = argparse.ArgumentParser()
parser.add_mutually_exclusive_group()

脚本调用

module = import_module("scripts.train")
modulenew = module.train
Modulenew(100)

在scripts目录下的train.py文件

def train(args):
    print("script:train")
	print("script:",args)

在scripts目录下要有__init__.py文件,使其成为一个模块

文件操作:

目录获取

def get_folder(path, make_folder=True):
    """ Return a path to a folder, creating it if it doesn't exist """
    logger = logging.getLogger(__name__)  # pylint:disable=invalid-name
    logger.debug("Requested path: '%s'", path)
    output_dir = Path(path)
    if not make_folder and not output_dir.exists():
        logger.debug("%s does not exist", path)
        return None
    output_dir.mkdir(parents=True, exist_ok=True)
    logger.debug("Returning: '%s'", output_dir)
    return output_dir

目录下文件获取并排序

dir_scanned = sorted(os.scandir(directory), key=lambda x: x.name)

文件过滤

_image_extensions = [  # pylint:disable=invalid-name
    ".bmp", ".jpeg", ".jpg", ".png", ".tif", ".tiff"]

for chkfile in dir_scanned:
    if any([chkfile.name.lower().endswith(ext)
            for ext in image_extensions]):
        dir_contents.append(chkfile.path)

文件操作with

在with的缩进内可以操作文件对象,一旦取消缩进,资源就被释放了

with open('target.txt', 'r', encoding='utf-8') as rf:
    # 文件操作的具体代码
    pass
# 缩进一旦取消缩进,资源就被释放了

异常:try-except-else-finally

在try中发生的错误,会被except捕获,如果没有发生错误,则会执行else块,finally块是无论如何都会执行的块。

模块新建,模块导入

模块以文件夹的方式组织,只要在一个文件夹中有__init__.py文件。
模块导入使用import 或者 from import 方法

生成器

使用生成器在迭代大量数据时,可以有效减少内存占用。在生成器函数的每次循环中,把本来需要生成序列的元素使用yield返回。生成器函数可以在for循环中使用,使代码更加简洁,内存占用减少。下面是一个从视频中提取每一帧图片的生成器例子。

视频中提取图片

def from_video(location):
    logger.debug("Loading frames from video: '%s'", location)
    reader = imageio.get_reader(location, "ffmpeg")
    for idx, frame in enumerate(reader):
        frame = frame[:, :, ::-1]
        yield frame
reader.close()
使用生成器
filename = "output.mp4"
for frame in from_video(filename):
    cv2.imshow("frame",frame) # pylint:disable=no-member
    cv2.waitKey(10) # pylint:disable=no-member

线程

threading.Thread类:
使用Thread类,可以有三种方法创建线程:
创建Thread类的实例,传递一个函数以及需要的参数
创建Thread类的实例,传递一个可调用的类实例(类继承自object,并有__call__函数)
派生Thread类的子类,并创建子类的实例。
线程创建后,调用start开始执行线程,如果调用了join,则主线程或等待线程执行完毕。

futures.ThreadPoolExecutor() 的线程池类:
使用submit提交待执行的任务,使用cancel取消任务(已经开始的任务无法取消),result函数获取结果,这个函数是阻塞的。done函数判断函数是否执行完毕。使用as_completed函数一次取出所有结果,但是该函数是一个生成器,只要有任务完成,就会返回,然后阻塞,循环知道所有任务结束。

executor = futures.ThreadPoolExecutor()
with executor:
    images = [executor.submit(read_image, filename, raise_error=True)
              for filename in filenames]
    batch = np.array([future.result() for future in futures.as_completed(images)])

这是一段读取大量图片的代码,会并行读取filenames中的图片,属于IO密集型的应用,只要有一个线程读完,就会生成到列表中。最后结果放到batch中。

Csv文件读取(pandas)

import pandas as pd
data = pd.read_csv("data.csv")
# 查看数据描述
data.head(10)
data.info()
data.isnull().sum() # 每个空行字段各有多少个
target = train["Survived"]  #获取任一列

Pandas的DataFrame:

data = pd.DataFrame({'Yes':[50,21],'No':[131,2]})
data = pd.DataFrame({
    'Bob': ['I liked it.', 'It was awful.'], 
    'Sue': ['Pretty good.', 'Bland.']})

data = pd.DataFrame({
    'Bob': ['I liked it.', 'It was awful.'], 
    'Sue': ['Pretty good.', 'Bland.']},
    index=['Product A', 'Product B'])

print(data)

Pandas的索引:

print(data.Bob)
print(data['Bob'])
print(data['Bob'][0])
print(data.iloc[0,0])  #位置索引
print(data.loc['Product B','Bob']) #标签索引
print(data.loc[(data.Bob == 'I liked it.') & (data.Sue == 'Pretty good.')])

Pandas的DataFrame还有很多其他的函数,实现更加复杂的操作,需要在另外的文章中介绍。

发布了113 篇原创文章 · 获赞 132 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/iamqianrenzhan/article/details/103444374
今日推荐