python 小技巧
Published:
开始写 python 之后才发现一堆不会的,有一点不会就查一点最后补充到这,未完待续。
输入输出
# 从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符)
str = input("请输入:")
# 标准输出
# '\r' 可刷新当前行输出结果,当 i 有位数变化时可能出错,需要用 format 格式化输出
# end 指定结尾:'\n' 换行,'' 不换行
print('\r', i, end='')
format()
格式化函数
# 不设置指定位置,按默认顺序
print("{} {}".format("hello", "world")) # 'hello world'
# 设置指定位置
print("{0} {1}".format("hello", "world")) # 'hello world'
# 设置指定位置
print("{1} {0} {1}".format("hello", "world")) # 'world hello world'
# 通过字典设置参数
print("名字: {name}, 地址: {url}".format(name="hello", url="world"))
# 通过字典设置参数
site = {"name": "hello", "url": "world"}
print("名字: {name}, 地址: {url}".format(**site))
# 通过列表索引设置参数
site = ['hello', 'world']
print("名字: {0[0]}, 地址: {0[1]}".format(site)) # "0" 是必须的
指定格式输出:
:
号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。^, <, >
分别是居中、左对齐、右对齐,后面带宽度。+
表示在正数前显示 +,负数前显示 -b, d, o, x
分别是二进制、十进制、八进制、十六进制。可以使用大括号
{}
来转义大括号
print("{:.0f}".format(3.1415926)) # 3
print("{:.2f}".format(3.1415926)) # 3.14
print("{:+.2f}".format(3.1415926)) # +3.14
print("{:+.2f}".format(-3.1415926)) # -3.14
print("{:0^4d}".format(5)) # 0500
print("{:0>4d}".format(5)) # 0005
print("{:>4d}".format(5)) # 5
print("{:x<4d}".format(5)) # 5xxx
print("{:b}".format(11)) # 1011
print("{:x}".format(11)) # b
print("{:#x}".format(11)) # 0xb
print("{:#X}".format(11)) # 0XB
print ("0 is {}".format("good")) # {0} is good
时间
from datetime import datetime
total_starttime = datetime.now()
# your code here
total_endtime = datetime.now()
print('Total running time: ', (total_endtime - total_starttime).seconds, ' seconds! ')
now_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
tqdm
进度条
from tqdm import tqdm
for i in tqdm(range(100000)):
pass
func(*args, **kwargs)
函数
这是 Python 函数可变参数 args 及 kwargs
*args 表示任何多个无名参数,它是一个 tuple
**kwargs 表示关键字参数,它是一个 dict
测试代码如下:
def foo(*args,**kwargs):
print('args=',args)
print('kwargs=',kwargs)
print('**********************')
if __name__=='__main__':
foo(1,2,3)
foo(a=1,b=2,c=3)
foo(1,2,3,a=1,b=2,c=3)
foo(1,'b','c',a=1,b='b',c='c')
执行结果如下:
args= (1, 2, 3)
kwargs= {}
**********************
args= ()
kwargs= {'a': 1, 'c': 3, 'b': 2}
**********************
args= (1, 2, 3)
kwargs= {'a': 1, 'c': 3, 'b': 2}
**********************
args= (1, 'b', 'c')
kwargs= {'a': 1, 'c': 'c', 'b': 'b'}
**********************
**
字典传参
通过定义字典来传参数
def test(a, b=1, c=1):
print(a + b + c)
kwargs = {'a':3, 'c':3}
test(**kwargs, b=2)
匿名函数 lambda
python 使用 lambda 来创建匿名函数
sum = lambda arg1, arg2: arg1 + arg2
print("相加后的值为: ", sum(10, 20)) # 30
装饰器
from functools import wraps
def use_logging(level):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if level == "warn":
logging.warn("%s is running" % func.__name__) # 输出 'f'
elif level == "info":
logging.info("%s is running" % func.__name__) # 输出 'f'
return func(*args, **kwargs)
return wrapper
return decorator
@use_logging(level="warn")
def f(x):
"""does some math"""
return x + x * x
日志文件
使用 tee
# 将输出写入文件
python test.py | tee -a test.log
使用 logging
import logging
# 输出到标准输出流
# 配合以下命令使用可将输出写入文件
# python test.py | tee -a test.log
logging.basicConfig(stream=sys.stdout,
level=logging.DEBUG,
format='%(asctime)s %(levelname)s:%(message)s',
datefmt='%m/%d %H:%M:%S')
# 直接输出到文件
logging.basicConfig(filename="test.log", filemode="a",
level=logging.DEBUG,
format='%(asctime)s %(levelname)s:%(message)s',
datefmt='%m/%d %H:%M:%S')
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
使用 logger
import logging
import logging.handlers
logger = logging.getLogger("logger")
handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="test.log")
logger.setLevel(logging.DEBUG)
handler1.setLevel(logging.DEBUG)
handler2.setLevel(logging.DEBUG)
formatter = logging.Formatter(fmt="%(asctime)s %(levelname)s:%(message)s",
datefmt='%m/%d %H:%M:%S')
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)
logger.addHandler(handler1)
logger.addHandler(handler2)
logger.debug('This is a customer debug message')
logger.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')
//
运算符
//
运算符执行地板除法(向下取整除),它会返回整除结果的整数部分
*
、np.dot()
、np.multiply()
区别
list | np.array | np.mat() | |
---|---|---|---|
* | error | 点乘 | 叉乘 |
np.dot() | 一维内积,其他叉乘 | 一维内积,其他叉乘 | 叉乘 |
np.multiply() | 点乘 | 点乘 | 点乘 |
type
、dtype
、astype
用法
名称 | 描述 | 用法 |
---|---|---|
type() | 返回参数的数据类型 | type(a) |
dtype | 返回数组中元素的数据类型 | a.dtype |
astype() | 对数据类型进行转换 | a=a.astype(int) |
enumerate()
函数
seq = ['one', 'two', 'three']
for i, element in enumerate(seq):
print i, element
"""
0 one
1 two
2 three
"""
zip()
函数
train_X = [0, 1, 2]
train_Y = ['one', 'two', 'three']
for (x, y) in zip(train_X, train_Y):
print(x, y)
"""
0 one
1 two
2 three
"""
进制转换(二、八、十六进制的字符串)
普通方法
# 十进制转二进制
bin(18) # '0b10010'
# 十进制转八进制
oct(18) # '0o22'
# 十进制转十六进制
hex(18) # '0x12'
# 二进制转十进制
int('0b10010',2) # 18
# 八进制转十进制
int('0o22',8) # 18
# 十六进制转十进制
int('0x12',16) # 18
指定位数
# 十进制转二进制字符串(二进制位数为 8,高位填充 0)
('{:0' + str(8) + 'b}').format(18) # '00010010'
类型转换
# str 类型转 list
list('010') # ['0', '1', '0']
# 将 list 中的 str 元素都转换为 int
list(map(int, ['0', '1', '0'])) # [0, 1, 0]
# 将 list 中的 int 元素都转换为 str
list(map(str, [0, 1, 0])) # ['0', '1', '0']
# 将 list 类型(元素为字符串)转换为字符串
''.join(['0', '1', '0'])
__future__
模块
Python提供了 __future__
模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性。
from __future__ import
查看函数说明
help(sum)
设置随机种子
注意:若多次设置随机种子,以最后一次为准!
def init_seeds(seed=0):
random.seed(seed)
np.random.seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
调用 linux 命令
import os
os.system("ls")
抛出异常
assert expression [, message]
assert 1==1 # 条件为 true 正常执行
assert 1==2 # 条件为 false 触发异常
assert 1==2, '1 不等于 2' # 条件为 false 触发异常
函数调用的相对路径
# 返回的是当前工作目录,非当前的脚本文件目录,所以在函数调用中会出现相对路径出错的问题
print(os.getcwd())
# 获取当前脚本文件所在目录,然后根据这个目录来访问相对路径下的文件
file_path = os.path.dirname(__file__)
二维 list 创建
利用乘法来创建二维 list 时会导致后面几行其实是第一行的一个浅拷贝,它们的地址是一样的,给任意一个赋值其余的也会被赋值。
l = [[0] * 3] * 3 # 错误
l = [[0] * 3 for i in range(3)] # 正确
t检验
from scipy.stats import ttest_ind_from_stats
ttest_ind_from_stats(mean1=1, std1=0.1, nobs1=5,
mean2=2, std2=0.2, nobs2=5)
argparse
import argparse
parser = argparse.ArgumentParser("introduction")
parser.add_argument("--a", type=str, default="test", help="help")
parser.add_argument("--b", type=int, default=1)
parser.add_argument("--c", type=float, default=0.1)
parser.add_argument("--d", action="store_true", default=False) # 可不需要 default,store_true 默认 False
parser.add_argument("--d", action="store_false", default=True) # 可不需要 default,store_false 默认 True
config = parser.parse_args()
查看某个库文件位置
import gym
gym.__file__