目录
一 当前文件路径
os.path.abspath('.')
二 python路径拼接os.path.join()函数的用法
我们都知道对于不同的系统,系统路径的分隔符是不一样的:Windows系统为“\”,Linux系统为“/”,Mac OS系统为“:”。
我们平时对系统文件路径进行操作时,通常用“+”和不同系统的分隔符进行拼接。那么有没有一种方法能够在我们跨平台时,不需要修改自己的代码,而实现这一操作呢?
os模块中的os.oath.join(path, name)可以连接目录与文件名或目录。我们使用这个方法,就能够实现跨平台的文件操作。
os.path.join()
:连接两个或更多的路径名组件,如果各组件名首字母不包含’/’,则函数会自动加上,如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃,如果最后一个组件为空,则生成的路径以一个’/’分隔符结尾。
import os
Path1 = 'home'
Path2 = 'develop'
Path3 = 'code'
Path10 = Path1 + Path2 + Path3
Path20 = os.path.join(Path1, Path2, Path3)
print('Path10 = ', Path10)
print('Path20 = ', Path20)
输出如下:
Path10 = homedevelopcode
Path20 = home/develop/code
import os
Path1 = '/home'
Path2 = 'develop'
Path3 = 'code'
Path10 = Path1 + Path2 + Path3
Path20 = os.path.join(Path1, Path2, Path3)
print(Path10 = ', Path10)
print(Path20 = ', Path20)
输出如下:
Path10 = /homedevelopcode
Path20 = /home/develop/code
import os
Path1 = 'home'
Path2 = '/develop'
Path3 = 'code'
Path10 = Path1 + Path2 + Path3
Path20 = os.path.join(Path1, Path2, Path3)
print(Path10 = ', Path10)
print(Path20 = ', Path20)
输出如下:
Path10 = home/developcode
Path20 = /develop/code
import os
Path1 = 'home'
Path2 = 'develop'
Path3 = '/code'
Path10 = Path1 + Path2 + Path3
Path20 = os.path.join(Path1, Path2, Path3)
print(Path10 = ', Path10)
print(Path20 = ', Path20)
输出如下:
Path10 = homedevelop./code
Path20 = home/develop/./code
三 print格式化输出
%r
:用来做 debug 比较好,因为它会显示变量的原始数据(raw data),而其它的符号则是用来向用户显示输出的。
1、打印字符串
print ("His name is %s"%("Aviad"))
效果:
2.打印整数
print ("He is %d years old"%(25))
效果:
3.打印浮点数
print ("His height is %f m"%(1.83))
效果:
4.打印浮点数(指定保留小数点位数)
print ("His height is %.2f m"%(1.83))
效果:
5.指定占位符宽度
print ("Name:%10s Age:%8d Height:%8.2f"%("Aviad",25,1.83))
效果:
6.指定占位符宽度(左对齐)
print ("Name:%-10s Age:%-8d Height:%-8.2f"%("Aviad",25,1.83))
效果:
7.指定占位符(只能用0当占位符?)
print ("Name:%-10s Age:%08d Height:%08.2f"%("Aviad",25,1.83))
效果:
8.科学计数法
format(0.0015,'.2e')
效果:
我们还可以用词典来传递真实值。如下:
print ("I'm %(c)s. I have %(l)d yuan." % {'c':'hungry','l':22})
调试输出:
I’m hungry. I have 22 yuan.
格式符
格式符为真实值预留位置,并控制显示的格式。格式符可以包含有一个类型码,用以控制显示的类型,如下:
%s
字符串 (采用str()的显示)
%r
字符串 (采用repr()的显示)
%c
单个字符
%b
二进制整数
%d
十进制整数
%i
十进制整数
%o
八进制整数
%x
十六进制整数
%e
指数 (基底写为e)
%E
指数 (基底写为E)
%f
浮点数
%F
浮点数,与上相同
%g
指数(e)或浮点数 (根据显示长度)
%G
指数(E)或浮点数 (根据显示长度)
%%
字符"%"
可以用如下的方式,对格式进行进一步的控制:
%[(name)][flags][width].[precision]typecode
(name)为命名
flags可以有+,-,’ ‘或0。+表示右对齐。-表示左对齐。’ '为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填充。
width表示显示宽度
precision表示小数点后精度
比如:
print("%+10x" % 10)
print("%04d" % 5)
print("%6.3f" % 2.3)
上面的width, precision为两个整数。我们可以利用*,来动态代入这两个量。比如:print("%.*f" % (4, 1.2))
,Python实际上用4来替换*。所以实际的模板为"%.4f"。
总结:Python中内置的%操作符可用于格式化字符串操作,控制字符串的呈现格式。Python中还有其他的格式化字符串的方式,但%操作符的使用是最方便的。
四 将 print 输出到文件
import os
t = 5
s = 'hello world!'
with open('test.txt','a') as file0:
print('%d' % t,'%s' % s,file=file0)
print延迟问题,根源是python默认启用了stdout缓冲,解决的办法有两种:
一种办法是每次print后,都调用stdout flush(),把缓冲区打印出来,这个办法比较麻烦,要重载stdout,不推荐。最简单的方法是用命令行参数-u启动python,禁用stdout缓冲;
比如脚本是build-native.py,运行python -u build-native.py
就不会出现print延迟问题了。
五 log模块
本节内容来自这里。
1 配置文件
添加配置文件 logger_config.ini
。文件的后缀名其实无所谓,conf,ini
或者别的都行。我把该文件放置在/{$项目名}/resource/路径下。
重点1:TimedRotatingFileHandler
用来配置log的滚动删除,arg
里的“midnight”, 1, 6,’utf-8′
表示“每一天午夜12点将当天的日志转存到一份新的日志文件中,并且加上时间戳后缀,最多保存6个文件,编码格式UTF-8,支持中文”
重点2:如果要同时输出到2个文件和屏幕上,那么需要使用三个 handler
,2个为 TimedRotatingFileHandler
,还有1个是 StreamHandler
。
重点3:level
级别如下,级别越低,打印的日志越详细,例如级别为 noset
,则会打印出所有信息,如果级别为 info
,那么不会打印出 debug
信息。我们的例子中,级别为 info
,日志里不会打印出 debug
的信息。
下面是详细的配置文件:
[loggers]
keys=root
[handlers]
keys=rotatingFileHandler,streamHandler,errorHandler
[formatters]
keys=simpleFmt
[logger_root]
level=DEBUG
handlers=rotatingFileHandler,streamHandler,errorHandler
[handler_rotatingFileHandler]
class=handlers.TimedRotatingFileHandler
level=INFO
formatter=simpleFmt
args=(os.path.abspath(os.getcwd() + "/resource/ta_log/default.log"),"midnight", 1, 6,'utf-8')
[handler_errorHandler]
class=handlers.TimedRotatingFileHandler
level=ERROR
formatter=simpleFmt
args=(os.path.abspath(os.getcwd() + "/resource/ta_log/error.log"), "midnight", 1, 6,'utf-8')
[handler_streamHandler]
level=INFO
class=StreamHandler
formatter=simpleFmt
args=(sys.stdout,)
[formatter_simpleFmt]
format=%(asctime)s %(pathname)s(%(lineno)d): %(levelname)s %(message)s
2 全局log
编写globalLog.py 作为全局log的管理入口。后续别的模块下的python文件需要使用日志功能时,需要导入该模块。该模块的原理也很简单,定位到文件路径,然后通过logger的名字获得要用的logger配置,例如我上面的配置文件中:
[loggers]
keys=root
所以这里就用了root.然后创建一个全局的logger对象,命名为ta_log:
#globalLog.py
import logging
import logging.config
import os
def get_logger(name='root'):
conf_log = os.path.abspath(os.getcwd() + "/resource/logger_config.ini")
logging.config.fileConfig(conf_log)
return logging.getLogger(name)
ta_log = get_logger(__name__)
3 使用
在需要打印日志的地方使用该方法,例如在main.py里通过ta_log.info()打印日志。该方法会打印各个级别的信息进入两个日志文件中。我们在第四步来看一看日志文件的内容:
import sys
from globalLog import ta_log
if __name__ == '__main__':
ta_log.info("start")
try:
print(1 / 0)
except Exception:
ta_log.error("error:")
ta_log.exception(sys.exc_info())
ta_log.debug("end")
4 运行程序
运行程序,检查日志文件。
这是default.log,级别是info.没有记录ta_log.debug()的信息:
2018-08-31 13:09:34,928 C:/lzw_programming/test/main.py(6): INFO start
2018-08-31 13:09:34,928 C:/lzw_programming/test/main.py(10): ERROR error:
2018-08-31 13:09:34,930 C:/lzw_programming/test/main.py(11): ERROR (<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x0000000003B38888>)
Traceback (most recent call last):
File "C:/lzw_programming/test/main.py", line 8, in <module>
print(1 / 0)
ZeroDivisionError: integer division or modulo by zero
这是error.log。级别是error。没有记录ta_log.info()和ta_log.debug()的信息
2018-08-31 13:09:34,928 C:/lzw_programming/testassist/main.py(10): ERROR error:
2018-08-31 13:09:34,930 C:/lzw_programming/testassist/main.py(11): ERROR (<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x0000000003B38888>)
Traceback (most recent call last):
File "C:/lzw_programming/testassist/main.py", line 8, in <module>
print(1 / 0)
ZeroDivisionError: integer division or modulo by zero
5 结果
运行了3天主程序,查看是否滚动产生了新的日志信息,结果是把历史日志信息滚动复制到了新的文件里,后缀名为日期,如图。
六 删除文件
递归地删除文件:
shutil.rmtree(r'user\tester')
七 判断文件/文件夹是否存在
if not os.path.exists(path):
os.makedirs(path)
可以看出用os.path.exists()方法,判断文件和文件夹是一样。
其实这种方法还是有个问题,假设你想检查文件“test_data”是否存在,但是当前路径下有个叫“test_data”的文件夹,这样就可能出现误判。为了避免这样的情况,可以这样,只检查文件:
import os
os.path.isfile("test-data")
通过这个方法,如果文件”test-data”不存在将返回False,反之返回True。
八 文本文件操作
Python strip()
:方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列,返回分割后的列表。
九 pandas读文件(不把第一行作列属性)
read_csv("test.cvs",header=None)
:不把第一行作列属性。
十 图片显示
1 opencv
import cv2
img = cv2.imread("img.jpg")
cv2.imshow('image', img)
cv2.waitKey(0)
2 plt
import matplotlib.pyplot as plt
from PIL import Image
image= Image.open("img.jpg")
plt.figure("Image") # 图像窗口名称
plt.imshow(image)
plt.axis('off') # 关掉坐标轴为 off
plt.title('image') # 图像题目
plt.show()
十一 曲线设置
1、设置中文使用matplotlib.font_manager
,并重新定义字体font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14)
;
2、定义坐标轴标签位置plt.text(5, -5, ‘X axis (Year)…’, ha=‘left’, rotation=0, wrap=True)
;
3、定义坐标轴位置ax.xaxis.set_ticks_position(‘bottom’)
;
4、定义坐标轴刻度ax.set_xticklabels([‘2017’,‘2018’,’ ‘,‘2020’,‘2021’],rotation=45,fontsize=‘small’)
;
5、定义图名标题plt.title(u’测试函数’, fontproperties=font,loc=‘left’)
;
6、定义曲线上主要坐标点plt.annotate("(%s,%s)" % xy, xy=xy, xytext=(-20, 10), textcoords=‘offset points’)
。
# -- coding: utf-8 –
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"C:\Windows\Fonts\simhei.ttf", size=14)
x = np.linspace(-5, 5, 50)
x1 = np.linspace(-5, 5, 5)
y1 = 3 * x1 - 4
y2 = -2 * x * x + 33
y3 = 3 / x
plt.figure()
plt.text(5, -5, 'X axis (Year)…', ha='left', rotation=0, wrap=True) # 坐标轴标签重新设置
plt.text(-0.5, 30, 'Y axis…', ha='left', rotation=90, wrap=True)
ax = plt.gca() # get current axis 获得坐标轴对象
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none') # 将右边 上边的两条边颜色设置为空 其实就相当于抹掉这两条边
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left') # 指定下边的边作为 x 轴 指定左边的边为 y 轴
ax.spines['bottom'].set_position(('data', 0)) # 指定 data 设置的bottom(也就是指定的x轴)绑定到y轴的0这个点上
ax.spines['left'].set_position(('data', 0))
ax.set_xticks([-4, -2, 0, 2, 4]) # 设置坐标轴的标签显示方式
ax.set_xticklabels(['2017', '2018', ' ', '2020', '2021'], rotation=45, fontsize='small')
# 绘制图形的标题
plt.title(u'测试函数', fontproperties=font, loc='left') # ax.set_title('Demo Figure')设置图名、字体及位置
plt.plot(x1, y1, linestyle='-.', marker='o')
for xy in zip(x1, y1): # 在曲线上标注坐标点
plt.annotate("(%s,%s)" % xy, xy=xy, xytext=(-20, 10), textcoords='offset points')
plt.plot(x, y2, linestyle='-.', marker='.')
plt.plot(x, y3, linestyle=':', marker='1')
plt.show()
十二 sigmoid曲线
sigmoid曲线公式如下,可将值域限定在(0,1),在深度学习目标分类检测中常常用到,可限定坐标范围、分类概率。
s
(
x
)
=
1
1
+
e
−
x
s(x)=\frac{1}{1+e^{-x}}
s(x)=1+e−x1
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.1)
y = []
for t in x:
y_1 = 1 / (1 + math.exp(-t))
y.append(y_1)
plt.plot(x, y, label="sigmoid")
plt.xlabel("x")
plt.ylabel("y")
plt.ylim(0, 1) # y轴限制
plt.legend() # 用于给图像加图例,图例是集中于地图一角或一侧的地图上各种符号和颜色所代表内容与指标的说明,有助于更好的认识地图。
plt.show()
十三 sin & cos曲线
import numpy as np
import math
import matplotlib.pyplot as plt
#sin & cos曲线
x = np.arange(0, 6, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y1,label="sin")
plt.plot(x,y2,label="cos",linestyle = "--")
plt.xlabel("x")
plt.ylabel("y")
plt.title('sin & cos')
plt.legend() #打上标签
plt.show()
十四 lanczos曲线
lanczos曲线常常用在图像插值中,这个算法在放大和缩小中都能较好的抵制锯齿,在插值时,不仅有正的插值系数,也有负的系数,比较适用于自然图像。
L
(
x
)
=
{
s
i
n
c
(
x
)
s
i
n
c
(
x
a
)
if
−
a
<
x
<
a
0
otherwise
E
q
u
i
v
a
l
e
n
t
l
y
,
L
(
x
)
=
{
0
if
x
=
0
a
sin
(
π
x
)
sin
(
π
x
a
)
π
2
x
2
if
−
a
≤
x
<
a
and
x
≠
a
1
otherwise
L(x)= \begin{cases} sinc(x)sinc(\frac{x}{a}) \ \ \text{if}\ -a < x < a\\ 0\ \ \text{otherwise}\\ \end{cases} \\ Equivalently,\\ L(x)= \begin{cases} 0 \ \ \text{if}\ x=0\\ \frac{a\sin(\pi x)\sin(\frac{\pi x}{a})}{\pi^2x^2} \ \ \text{if}\ -a \leq x <a\ \text{and}\ x\not=a\\ 1 \ \ \text{otherwise}\\ \end{cases}
L(x)={sinc(x)sinc(ax) if −a<x<a0 otherwiseEquivalently,L(x)=⎩⎪⎨⎪⎧0 if x=0π2x2asin(πx)sin(aπx) if −a≤x<a and x=a1 otherwise
import numpy as np
import math
import matplotlib.pyplot as plt
#lanczos曲线
x = np.arange(-6, 6, 0.1)
a1 = 2
a2 = 3
a3 = 5
y1 = np.sinc(x) * np.sinc(x/a1)
y2 = np.sinc(x) * np.sinc(x/a2)
y3 = np.sinc(x) * np.sinc(x/a3)
plt.plot(x,y1,label="a=2")
plt.plot(x,y2,label="a=3",linestyle="--")
#plt.plot(x,y3,label="a=5",linestyle="--")
plt.title('sinc')
plt.legend() #打上标签
plt.show()
十五 jpeg编码的qp曲线
import numpy as np
import math
import matplotlib.pyplot as plt
#jpeg编码的qp曲线
x = np.arange(0.1, 100, 0.1) #从0.1到100,间隔0.1取点
y = []
for t in x:
if t < 50:
y_1 = 5000 / t
else:
y_1 = 200 - t * 2
y.append(y_1)
plt.plot(x, y, label="qp-quality")
plt.xlabel("quality")
plt.ylabel("qp")
plt.ylim(0, 500)
plt.legend() #显示label
plt.show()
上图中的纵坐标表示基于标准量化表的系数,也就是下面代码中的scale_factor,最终得到的temp值即为quality对应的量化表。
for (i = 0; i < DCTSIZE2; i++)
{
temp = ((long)basic_table[i] * scale_factor + 50L) / 100L;
/* limit the values to the valid range */
if (temp <= 0L) temp = 1L;
if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
if (force_baseline && temp > 255L)
temp = 255L; /* limit to baseline range if requested */
(*qtblptr)->quantval[i] = (UINT16)temp;
}