Python常规模块的用法

0.概述

本文记录一下python中的用法,作为简单的记录,必要时再予以补充。

1.argparse用法

argparse是Python内置的命令行参数解析模块。在使用add_argument方法时,可以通过action参数指定对参数的特殊处理方式。下面将详细介绍parser.add_argument中的action使用的完整攻略,包括常用的几种action和它们的用法。

1)action='store'

使用store时,将参数值存储到args的命名空间中。如果在命令行中指定了参数,则存储指定的参数值;否则,将使用默认值。例如:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store', default='bar')
args = parser.parse_args()

print(args.foo)

上面的代码在命令行中运行时不指定--foo参数值,则args.foo的值为'bar'

2) action='store_const'

使用store_const时,将常量(const)值存储到args的命名空间中,该常量值与指定的参数名相对应。如果在命令行中指定了该参数,则将该常量值存储到args的命名空间中。例如:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store_const', const=42)
args = parser.parse_args()

print(args.foo)

上面的代码在命令行中运行时指定--foo参数,则args.foo的值为42;否则为None

3) 其他常用action选项

除了上述两种action选项,还有一些常用的选项:

  • store_true: 将布尔值True存储到args的命名空间中。
  • store_false: 将布尔值False存储到args的命名空间中。
  • append: 将值追加到列表中。
  • append_const: 将常量值追加到列表中。
  • version: 打印程序版本号并退出。

下面是store_truestore_false的示例:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store_true')
parser.add_argument('--bar', action='store_false')
args = parser.parse_args()

print(args.foo)
print(args.bar)

上面的代码在命令行中运行时指定--foo参数,则args.foo的值为True;若指定--bar参数,则args.bar的值为False

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--debug', dest='debug_mode', action='store_true')
parser.add_argument('--no-debug', dest='debug_mode', action='store_false')
parser.set_defaults(debug_mode=False)
args = parser.parse_args()

print(args.debug_mode)

上面的代码在命令行中运行时指定--debug参数,则args.debug_mode的值为True; 若指定--no-debug参数,则args.debug_mode的值为False。若不指定任何参数则默认为False

这就是parser.add_argument中的action使用的完整攻略。

2.datetime

datetime是模块,datetime模块还包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类。

strptime():str-parse-time  # string to datetime

strftime():str-format-time  # datetime to  string

1) strptime

用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过datetime.strptime()实现,需要一个日期和时间的格式化字符串:

 >>> from datetime import datetime
 >>> cday = datetime.strptime('2022-3-1 18:20:20', '%Y-%m-%d %H:%M:%S')
 >>> print(cday)
 2022-03-01 18:20:20

2) strftime

后台提取到datetime对象后,要把它格式化为字符串显示给用户,就需要转换为str,转换方法是通过strftime()实现的,同样需要一个日期和时间的格式化字符串:

>>> from datetime import datetime
>>> now = datetime.now()
>>> print(now.strftime('%a, %b %d %H:%M'))
Sun, May 01 00:16

3) datetime加减:

对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime。加减可以直接用+和-运算符,不过需要导入timedelta这个类:

>>> from datetime import datetime, timedelta
>>> now = datetime.now()
>>> now
datetime.datetime(2022, 5, 1, 0, 16, 59, 248600)
>>> now + timedelta(hours=10)
datetime.datetime(2022, 5, 1, 10, 16, 59, 248600)
>>> now - timedelta(days=1)
datetime.datetime(2022, 4, 30, 0, 16, 59, 248600)
>>> now + timedelta(days=2, hours=12)
datetime.datetime(2022, 5, 3, 12, 16, 59, 248600)

3.sort

partial_indices.sort(key = lambda x: lengths[x], reverse = True)

#e.g: 
partial_indices = [2,3,5,1,0,4]
lengths=[9,6,7,2,3,5,18,11]

#firstly,  get value=[7, 2, 5, 6, 9, 3]
value=[lengths[x] for x in partial_indices]

#then, get value= [9, 7, 6, 5, 3, 2]
value.sort(reverse = True) 

#lastly, get the index of the sorted [9, 7, 6, 5, 3, 2] in original [9,6,7,2,3,5,18,11]

# result is: 
[0, 2, 1, 5, 4, 3]

4.multiprocessing

import threading

class MyThread(threading.Thread):
    def __init__(self, func, args=[()], name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args
        self.result = []

    def run(self):
        for arg in self.args:
            if arg is None:
                self.result.append(self.func())
            else:
                self.result.append(self.func(*arg))

    def get_result(self):
        return self.result

def StartThreadTask(func, args=[()], thrd_cnt=1, is_syn=True):
    thrd_lst = []

    cnt = int(len(args)/thrd_cnt)  # e.g  int(18/16)=1
    thrd_cnt1 = len(args)%thrd_cnt   # e.g  2
    cnt1 = cnt+1 # e.g  2
    for i in range(thrd_cnt1): # 0~1
        thrd_args = args[i*cnt1:i*cnt1+cnt1]
        thrd = MyThread(func, thrd_args, str(i))
        thrd_lst.append(thrd)  # A thread list,length:5
    for i in range(thrd_cnt1,thrd_cnt): # range:5~15
        thrd_args = args[thrd_cnt1+i*cnt:thrd_cnt1+i*cnt+cnt] # e.g args[5+0:5+0+0]
        thrd = MyThread(func, thrd_args, str(i))
        thrd_lst.append(thrd)

    for thrd in thrd_lst:
        thrd.start()

    if is_syn:
        result = []
        for thrd in thrd_lst:
            thrd.join()
            result += thrd.get_result() 

        return result

5.format用法

对于Python3 开始,以下列出三种常用的字符串格式化的功能。

1)C语音相似的占位符格式化输出(古老版本)

name='scott'
age=11
print("My name is %s,My age is %d" %(name,age))

2) format一般化格式化输出(常用版本)

name='scott'
age=11
print("My name is %s,My age is %d" %(name,age))

3)数字格式化

下表展示了 str.format() 格式化数字的具体方法,涵盖多种形式:

>>> print("{:.2f}".format(3.1415926));
3.14
数字格式输出描述
3.1415926{:.2f}3.14保留小数点后两位
3.1415926{:+.2f}+3.14带符号保留小数点后两位
-1{:+.2f}-1.00带符号保留小数点后两位
2.71828{:.0f}3不带小数
5{:0>2d}05数字补零 (填充左边, 宽度为2)
5{:x<4d}5xxx数字补x (填充右边, 宽度为4)
10{:x<4d}10xx数字补x (填充右边, 宽度为4)
1000000{:,}1,000,000以逗号分隔的数字格式
0.25{:.2%}25.00%百分比格式
1000000000{:.2e}1.00e+09指数记法
13{:10d}        13右对齐 (默认, 宽度为10)
13{:<10d}13左对齐 (宽度为10)
13{:^10d}    13中间对齐 (宽度为10)
11
'{:b}'.format(11)
'{:d}'.format(11)
'{:o}'.format(11)
'{:x}'.format(11)
'{:#x}'.format(11)
'{:#X}'.format(11)
1011
11
13
b
0xb
0XB
进制

^, <, > 分别是居中、左对齐、右对齐,后面带宽度, : 号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。

+ 表示在正数前显示 +,负数前显示 -;  (空格)表示在正数前加空格

b、d、o、x 分别是二进制、十进制、八进制、十六进制。

此外我们可以使用大括号 {} 来转义大括号,如下实例:

3)最新 f-strings (进化版本)

在Python 3.6中引入 了f-strings,不仅比str.format使用简单,而且效率更高。

name='scott'
age=11
#{}中直接使用变量
print(f'My name is {name},My age is {age}')
#{}中运行表达式
print(f'{1**2+2**2+3**2}')
#调用Python内置函数
print(f'{name.upper()}')
#用lambda匿名函数:可以做复杂的数值计算
fun = lambda x : x+1
print(f'{fun(age)}')

6.dict用法

1) 使用key查找单个值

dict1 = {'name': 'Jhon', 'age': 23, 'love': 'C++'}
print(dict1['age']) # 使用键查找值
返回结果:23

2) 使用get()方法查找key对应的值

dict1 = {'name': 'Jhon', 'age': 23, 'love': 'C++'}

# 利用get函数使用key查找值,如果key存在返回value
print(dict1.get('age')) #23

# 利用get函数使用key查找值,如果key不存在返回None
print(dict1.get('age'))  #None

# 利用get函数使用key查找值,如果key存在返回value, 如果key不存在返回指定值XXX
print(dict1.get('age2', 'XXX')) # XXX

3) 使用setdefault()查找

setdefault和get函数差不多,当key不存在,则查找的内容当做key放入dict,并设置默认值,设置为None
dict1 = {'name': 'Jhon', 'age': 23, 'love': 'C++'}
print(dict1.setdefault('age2'))
age2不存在,返回None

 4) 查询所有键和值以及键值对

dict1 = {'name': 'Jhon', 'age': 23, 'love': 'C++'}
# keys()  # 获取所有的键,返回列表
print(dict1.keys())

# values()  # 获取所有的值,返回列表
print(dict1.values())

# items()  # 获取所有键值对,返回元祖组成的列表
print(dict1.items())

  5) 判断是否为有效dict

def getDictKey(myDict, value):
    if not isinstance(myDict, dict): # 判断是否为dict
        return False
    keyList = []
    for k, v in myDict.items():
        if v == value:
            keyList.append(k)
    return keyList

d = "{'中国':'北京', '首都':'北京', '山东':'济南', '余额': 99.99}"
print("getDictKey(d, '北京')=", getDictKey(d, '北京'))

# output:
getDictKey(d, '北京')= False

7. itertools模块chain遍历

使用chain模块遍历多个可迭代对象。

from itertools import chain
chain(*iterables)
将多个可迭代对象进行合并,相当于如下代码:
def chain(*iterables):
    # chain('XYZ', 'DEF') --> X Y Z D E F
    for it in iterables:
        for element in it:
            yield element
 
############ ex.01
ops={}
ops['missing'] = ['gx_mean','gy_mean']
ops['collinear'] = ['gx_skew','gy_skew',]
ops['zero_importance'] = ['gx_kurt','gy_kurt']
ops['low_importance'] = ['gx_range','gy_range']
from itertools import chain
all_identified = set(list(chain(*list(ops.values()))))
all_identified
Out[112]: 
{'gx_kurt',
 'gx_mean',
 'gx_range',
 'gx_skew',
 'gy_kurt',
 'gy_mean',
 'gy_range',
 'gy_skew'}


ops['missing'] = ['gx_mean','gy_mean','gz_mean','ax_mean','ay_mean','az_mean',
                     'gx_std','gy_std','gz_std','ax_std','ay_std','az_std']

8.增强型赋值

增强型赋值语句是经常被使用到的,因为从各种学习渠道中,我们能够得知 i += 1 的效率往往要比 i = i + 1 更高一些(这里以 += 为例,实际上增强型赋值语句不仅限于此)。所以我们会乐此不疲的在任何能够替换普通赋值语句的地方使用增量型赋值语句,以此来优化代码。那么我们是否有想过,在什么情况下 i += 1 其实并不等效于 i = i + 1 !!

例一:使用增强型赋值语句:

In [1]: a = [1, 2, 3]

In [2]: b = a

In [3]: b += [1, 2, 3]

In [4]: print a, b

[1, 2, 3, 1, 2, 3] [1, 2, 3, 1, 2, 3]

In [5]: id(a), id(b)

Out[5]: (140213762276096, 140213762276096)

例二:使用普通赋值语句:

In [6]: a = [1, 2, 3]

In [7]: b = a

In [8]: b = b + [1, 2, 3]

In [9]: print a, b

[1, 2, 3] [1, 2, 3, 1, 2, 3]

In [10]: id(a), id(b)

Out[10]: (140213762466232, 140213762276168)

 上述两个例子中,将一个列表类型对象赋值给变量 a,再将变量 a 赋值给变量 b,此时 a、b 指向了同一个内存对象 [1, 2, 3]。然后分别应用增量赋值运算符和普通赋值运算符来操作变量 b。从最后的结果来看,例一中的 a、b 在进行运算后依旧指向了同一个内存对象。例二则相反,a、b 分别指向了不同的内存对象,也就是说在例二中隐式的新建了一个内存对象。

这里写图片描述

这是一个值得注意的坑,警惕我们在使用增量赋值运算符来操作可变对象(如:列表)时可能会产生不可预测的结果。

要解释这个问题,首先需要了解「Python 共享引用」的概念:在 Python 中,允许若干个不同的变量引用指向同一个内存对象。同时在前文中也提到,增强赋值语句比普通赋值语句的效率更高,这是因为在 Python 源码中, 增强赋值比普通赋值多实现了“写回”的功能,也就是说增强赋值在条件符合的情况下(例如:操作数是一个可变类型对象)会以追加的方式来进行处理,而普通赋值则会以新建的方式进行处理。这一特点导致了增强赋值语句中的变量对象始终只有一个,Python 解析器解析该语句时不会额外创建出新的内存对象。所以例一中变量 a、b 的引用在最后依旧指向了同一个内存对象;相反,对于普通赋值运算语句,Python 解析器无法分辨语句中的两个同名变量(例如:b = b + 1)是否应该为同一内存对象,所以干脆再创建出一个新的内存对象用来存放最后的运算结果,所以例二中的 a、b 从原来指向同一内存对象,到最后分别指向了两个不同的内存对象。

​这是一个不为人所熟知的问题,我们能得到的结论就是:尽量不要使用增量赋值运算符来处理任何可变类型对象,除非你对上述问题有了足够的了解。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scott198512

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值