python 3 学习笔记

1 py3 中 print 不换行,只需要增加参数 end = '' 就可以了。类似于: print(output, end = '')

2 如果在 py2 中想要使用 py3 的 print ,只需要在文件最上面增加 from future import print_function 即可。

参考: https://www.runoob.com/python/python-basic-syntax.html

3 python 中需要执行 linux 命令,可以使用 subprocess 来完成,如果阻塞式调用,如下命令即可。

command = "ping -c 1 baidu.com "
back = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
print("back0----", back[0].decode())  # 注意需要进行解码操作,默认输出的是字节
print("back1----", back[1].decode())  # back是一个元祖,可以通过元祖取值的方式获取结果

参考: https://blog.csdn.net/gymaisyl/article/details/90746983

4 如果 subprocess 非阻塞调用,如下代码:

import subprocess
proc = subprocess.Popen('ls',
                       shell=True,
                       stdout=subprocess.PIPE,
                       )
while proc.poll() is None:
    output = proc.stdout.readline()
    print output,
output = proc.communicate()[0]
print output,

参考: http://www.cocoachina.com/articles/45711

5 subprocess 非阻塞,如下代码也可以:

import shlex
import subprocess

if __name__ == '__main__':
    shell_cmd = 'python3 subprogram.py'
    cmd = shlex.split(shell_cmd)
    p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while p.poll() is None:
        line = p.stdout.readline()
        line = line.strip()
        if line:
            print('Subprogram output: [{}]'.format(line))
    if p.returncode == 0:
        print('Subprogram success')
    else:
        print('Subprogram failed')

参考: https://blog.csdn.net/cnweike/article/details/73620250

6 python3 从下位机接收到的信息包含 b' 开头,因为这个是字节组织的数据,而 python 内部使用的是 unicode,如果需要去掉,使用如下代码:

s.decode('utf8')

参考: https://blog.csdn.net/teavamc/article/details/77651771 https://blog.csdn.net/qq_44955537/article/details/107838566

7 python3 需要使用 numpy,需要安装,使用命令 pip3 install --user numpy,然后提示没有 pip3,那么使用 sudo apt install python3-pip 安装,然后再次使用 pip3 install --user numpy 安装 numpy,结果提示 pip 版本太低。 使用 pip3 install --upgrade pip,结果升级了之后,系统还是只认前面的旧版本 pip。要修复,只能:

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
sudo python3 get-pip.py --force-reinstall

这样就成功的更新到新的pip3 了。 参考: https://blog.csdn.net/u012529163/article/details/102973380

8 pip 使用国内的源:

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称 --user

参考: https://blog.csdn.net/qq_36184671/article/details/96871879

9 python 字符串转数字,只需要用 int() 把字符串框进去就行了。

10 安装 matplotlib 的时候,错误,提示需要安装 tk,输入命令 sudo apt-get install python3-tk 安装成功就可以了。

11 列表最小值和最大值是 min(list), max(list)

12 matplotlib 数据更新,需要用多线程,后台线程准备数据,前台线程就是 matplotlib

l,= plt.plot(t, s, lw=2)
ydata = np.sin(4*np.pi*t)
#更新数据
l.set_xdata(t-t[0])
l.set_ydata(ydata)
#重新绘制图形
plt.draw()

参考: https://blog.csdn.net/chengqiuming/article/details/78601415

13 matplotlib 坐标轴极限值调整:

# 设置坐标轴的取值范围
plt.xlim((-1, 1))
plt.ylim((0, 2))

# 设置x坐标轴刻度, 原来为0.25, 修改后为0.5
plt.xticks(np.linspace(-1, 1, 5))
# 设置y坐标轴刻度及标签, $$是设置字体
plt.yticks([0, 0.5], ['$minimum$', 'normal'])

参考: https://www.jianshu.com/p/9a6ec706c642 https://www.cnblogs.com/htfeng/p/9931693.html https://blog.csdn.net/qq_26443737/article/details/82693387 https://blog.csdn.net/u013700358/article/details/82263250

14 多线程,python3 建议使用 threading.Thread

t=threading.Thread(target=sayhi,args=('hh',))
t.start()

参考: https://www.runoob.com/python3/python3-multithreading.html https://www.cnblogs.com/guyuyun/p/11185832.html https://blog.csdn.net/drdairen/article/details/60962439 https://www.cnblogs.com/guyuyun/p/11185832.html

15 matplotlib 一张图中的多子图显示,需要用 subplot,建议使用 subplot2grid 来定义子图的位置。如果要同时显示多图,那么只能用 figrue(n)来了,这个会打开多张图。

plt.figure(figsize=(12, 10), dpi=80)
plt.figure(1)
ax1=plt.subplot2grid((3,3),(0,0),colspan=3,rowspan=1)#相当于格子分成3行3列,列跨度为3,行跨度为1
ax1.plot([1,2],[1,2]) #轴的范围,x轴,y轴。 
ax1.set_title('ax1_title')
ax2=plt.subplot2grid((3,3),(1,0),colspan=2,rowspan=1)
ax2.plot([2,4,6],[7,9,15])
ax3=plt.subplot2grid((3,3),(1,2),colspan=1,rowspan=1)
x = np.arange(4)
y = np.array([15,20,18,25])
ax3.bar(x,y)
ax4=plt.subplot2grid((3,3),(2,0),colspan=1,rowspan=1)
ax5=plt.subplot2grid((3,3),(2,1),colspan=2,rowspan=1)

参考: https://www.cnblogs.com/dengfaheng/p/12720431.html

16 matplotlib 中的 subplot 修改坐标轴范围,需要用 ax1.set_ylim([0,1000]) 这样来。

参考: https://www.javaroad.cn/questions/27171

17 numpy.linspace() 这个函数返回的不是列表,需要这样写才行: encoderLeftList = list(numpy.linspace(0, plotNum, plotNum))

参考: https://jingyan.baidu.com/article/6b182309d9cf4dba59e1596c.html https://numpy.org/doc/stable/reference/generated/numpy.linspace.html

18 用 matplotlib 画图细节方面可以参考 : https://zhuanlan.zhihu.com/p/139052035 这个讲的很全面。

https://blog.csdn.net/fei347795790/article/details/90641817 https://matplotlib.org/api/pyplot_api.html#module-matplotlib.pyplot https://www.cnblogs.com/shaosks/p/9849446.html

19 python 作为模块和非模块,可以通过 name 来判断:

print('__name__ value: ', __name__)

def main():
    print('this message is from main function')

if __name__ == '__main__':

参考: https://www.cnblogs.com/keguo/p/9760361.html

20 python 生成列表,直接使用如下的代码:

value = [i for i in range(0, 10)]

上面的代码生成了 10 个数的列表。从 0 到 9. 参考: https://blog.csdn.net/qq_40628106/article/details/85039366

21 matplotlib 可以打开多个图片,每个图片包含多个子图。主要是通过 figure(n) 来选择当前是哪个图片,然后对应的进行相应的图片上面添加子图。

22 当用多个 figure 的时候,直接在子线程中调用 plt.draw 会报错 RuntimeError: main thread is not in main loop。 暂时没有找到好的方法。只用一个 figure 的时候,就没有问题。

23 python 多文件编程,参考:

https://blog.csdn.net/weixin_45564064/article/details/102246414

24 ubuntu 安装 pip3:

sudo apt-get install python3-pip
pip3 -V

配置为国内 清华 源

mkdir ~/.pip
vim ~/.pip/pip.conf
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn

参考: https://blog.csdn.net/qq_43590972/article/details/88617999

25 安装 pyalsaaudio 库, 注意,需要的 alsa/asoundlib.h 可以在 libasound2-dev 中获得。

sudo apt install libasound2-dev
pip3 install pyalsaaudio --user

注意,如果使用 --user ,那么就会安装到 ~/.local/lib/python3.6/site-packages/ 这个目录下面,否则是安装到 /usr/local/lib/python3.6/site-packages 下面。

pyalsaaudio 库中 pcm() 的参数是:PCM_PLAYBACK (0) or PCM_CAPTURE (1)"

参考: https://github.com/larsimmisch/pyalsaaudio http://larsimmisch.github.io/pyalsaaudio/ http://larsimmisch.github.io/pyalsaaudio/libalsaaudio.html#pcm-objects http://larsimmisch.github.io/pyalsaaudio/terminology.html https://github.com/greghesp/assistant-relay/issues/49

26 播放音频,需要安装 sox ,ffmpeg 库

sudo apt install libsox-dev
sudo apt install ffmpeg ffmpeg-doc
sudo apt install libavcodec-extra
sudo apt install portaudio19-dev portaudio19-doc python3-pyaudio python-pyaudio-doc

pydub 依赖 pyaudio,ffmpge,libavcodec-extra。pyaudio 依赖 portaudio19-dev,如果没有安装,就会报错:error: portaudio.h: No such file or directory

pip3 install pyaudio --user
pip3 install pydub --user
pip3 install pysox --user

参考: https://github.com/jiaaro/pydub/ https://blog.csdn.net/qq_42881421/article/details/88070942 https://stackoverflow.com/questions/48690984/portaudio-h-no-such-file-or-directory https://techoverflow.net/2019/08/05/how-to-fix-pyaudio-fatal-error-portaudio-h-no-such-file-or-directory/

27 回音消除时,需要安装 speexdsp 库

sudo apt install libspeexdsp-dev
sudo apt install swig
pip3 install --user speexdsp

注意: 安装 speexdsp 的时候,依赖 swig,如果没有,会报错: unable to execute 'swig': No such file or directory 参考: https://github.com/certbot/certbot/issues/34 https://github.com/xiph/speexdsp

28 post 请求

# 简单例子
import urllib.request
request = urllib.request.Requests('https://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

# 增加header
from urllib import request, parse
url = 'http://httpbin.org/post'
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
    'Host':'httpbin.org'
}
# 构造POST表格
dict = {
    'name':'Germey'
}
data = bytes(parse.urlencode(dict),encoding='utf8')
req = request.Request(url=url,data=data,headers=headers,method='POST')
response = request.urlopen(req)
print(response.read()).decode('utf-8')
# 或者随后增加header
from urllib import request, parse
url = 'http://httpbin.org/post'
dict = {
    'name':'Germey'
}
req = request.Request(url=url,data=data,method='POST')
req.add_hader('User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

参考: https://www.jianshu.com/p/cfbdacbeac6e https://www.liaoxuefeng.com/wiki/1016959663602400/1019223241745024 https://www.cnblogs.com/Simple-Small/p/9830270.html

29 获取 mac 地址

import uuid
print(hex(uuid.getnode())[2:])

上面这个获得 MAC 地址如果第一位是 0 ,这个 0 就被吞了,所以这个不适合所有的网卡,建议用下面这种:

mac = uuid.UUID(int = uuid.getnode()).hex[-12:].upper()
print(":".join([mac[e:e+2] for e in range(0,11,2)]))

参考: https://www.jianshu.com/p/d7b51e897d56 https://www.cnblogs.com/black-mamba/p/7061342.html

30 模块调用不同路径下的文件,报错找不到文件。

path = os.path.realpath(__file__)
path = os.path.split(path)[0]
sys.path.append(os.path.split(os.path.realpath(__file__))[0] + "/../../../platform/source/speech")

建议用下面这种,下面这种路径自动补全比较方便。

sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "../../../platform/source/speech"))

absPath = os.path.abspath(os.path.dirname(__file__))
sys.path.append(os.path.join(absPath, "../../../platform/source/speech"))

参考: https://blog.csdn.net/cityzenoldwang/article/details/78448039 https://www.runoob.com/python/python-os-path.html https://www.cnblogs.com/hpzyang/p/10281298.html

31 音频文件转换,需要安装 ffmpeg-python. 注意不要安装成 pyffmpeg了,不是这个。

pip3 install ffmpeg-python

如果是转换 mp3 等格式,很简单,直接转换即可。

import ffmpeg
ffmpeg.input('input.mp3').output('output.mp3', ar=16000).run()

参考: https://www.v2ex.com/t/561239

如果是 pcm 这种格式,就麻烦了,需要更多的参数。

import ffmpeg
try:
    ins = ffmpeg.input("input.pcm", acodec = 'pcm_s16le', format = 's16le', ar=44100, ac=2)
    ins.output("output.pcm", acodec = 'pcm_s16le', format = 's16le', ar=16000, ac = 1).run()
except ffmpeg.Error as e:
    print('stdout:', e.stdout.decode('utf8'))
    print('stderr:', e.stderr.decode('utf8'))
    raise e

具体的参数设置可以参考 ffmpeg 的官网和 ffmpeg-python 的官网。有些地方配置有冲突的地方,比如说 acodec 如果配置为 pcm,那么就会报错。所以资料要对照着看,然后上机测试。 https://github.com/kkroening/ffmpeg-python/blob/master/examples/README.md#convert-sound-to-raw-pcm-audio https://ffmpeg.org/ffmpeg.html#Video-and-Audio-file-format-conversion https://kkroening.github.io/ffmpeg-python/

增加异常获取是为了获得更多的错误信息,可以参考: https://github.com/kkroening/ffmpeg-python/issues/165

当然也可以选择使用 sox,这个据说也可以用。 参考: https://pysox.readthedocs.io/en/latest/api.html https://blog.csdn.net/lucky_ricky/article/details/74587002

32. python3 删除文件

    #判断音频文件是否存在
    if(os.path.exists(AUDIO_FILE)):
        os.remove(AUDIO_FILE)

参考: https://www.linuxidc.com/Linux/2019-05/158470.htm https://blog.csdn.net/whatday/article/details/104187361

33. list 转为 str, 并以空格进行分隔。

strText = " ".join(asrText)

参考: https://blog.csdn.net/roytao2/article/details/53433373

34. import

参考: https://blog.csdn.net/cqbamboo/article/details/103012429 https://blog.csdn.net/weixin_44546620/article/details/104755730

35. python3 升级 pip3 的正确命令:

python3 -m pip install --upgrade pip --user

36. python 类的成员变量在 init 中都要写出并初始化。

参考: https://blog.csdn.net/gzhouc/article/details/46785797

37. python3 utf gbk 互转

s = '你好'
# 字符串s已经是unicode编码,无需decode,直接encode
s_to_gbk = s.encode("gbk")
print("----s_to_gbk----")
print(s_to_gbk)
#这边还是一样,gbk需要先解码成unicode,再编码成utf-8
gbk_to_utf8 = s_to_gbk.decode("gbk").encode("utf-8")
print("-----gbk_to_utf8---")
print(gbk_to_utf8)
#解码成unicode字符编码
utf8_decode = gbk_to_utf8.decode("utf-8")
print("-------utf8_decode----")
print(utf8_decode)

参考: https://www.jb51.net/article/179894.htm

38. 执行 linux 命令

import os
val = os.system('ls -al')

参考: https://www.cnblogs.com/mianbaoshu/p/12024498.html

39. 通过进程名获取进程号,使用 pidof

kill -9 `pidof python3`

40. 获取线程 id, 使用 ctypes.

参考: https://blog.csdn.net/tjcwt2011/article/details/80885410

41. python 单类模式

import threading
class Singleton(object):
    _instance_lock = threading.Lock()

    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = object.__new__(cls)  
        return Singleton._instance

obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)

def task(arg):
    obj = Singleton()
    print(obj)

for i in range(10):
    t = threading.Thread(target=task,args=[i,])
    t.start()

参考: https://zhuanlan.zhihu.com/p/37534850 https://www.cnblogs.com/huchong/p/8244279.html

42. python 有构造函数和析构函数

def __init__(self)
def __del__(self)

43. python 异常打印

        try:
            self.__alsaDev = alsaaudio.PCM(type = alsaaudio.PCM_PLAYBACK, mode = alsaaudio.PCM_NORMAL, rate = 16000, channels = 8, format = alsaaudio.PCM_FORMAT_S16_LE, periodsize = 160, device = "plughw:" + self.__devName)
        except Exception as e:
            print("alsaaudio open pcm exception: ", e)

44. 线程池 ThreadPool

参考: https://www.jianshu.com/p/b9b3d66aa0be https://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/chapter4/02_Using_the_concurrent.futures_Python_modules.html

45. 线程锁

参考: https://blog.csdn.net/S_o_l_o_n/article/details/92148720 http://c.biancheng.net/view/2617.html

46. 获取后缀名使用 os.path.splitext

portion = os.path.splitext(fileName)

portion[1] 里面就是后缀名,portion[0] 里面就是后缀名之前的内容。 参考: https://www.cnblogs.com/rychh/articles/9745932.html https://blog.csdn.net/rosefun96/article/details/78968490 https://my.oschina.net/u/4405061/blog/3327024 https://blog.csdn.net/JNingWei/article/details/78745403

47. 获取路径中的文件名 使用 os.path.basename

fileName = os.path.basename(path)

参考: https://blog.csdn.net/igolang/article/details/8021258

48. 获取路径中的文件名,后缀,目录等等。

(file, ext) = os.path.splitext(url)
print(file)
print(ext)

(path, filename) = os.path.split(url)
print(filename)
print(path)

上面的 file 打印出的是后缀名前面的所有东西不含 "." ,ext 打印出的是后缀名 含 ".",filename 打印出的是文件名,path 打印出的是目录 不含 "/" 参考: https://blog.csdn.net/lilongsy/article/details/99853925

49. 创建目录

os.mkdir(path)  #单层目录
os.makedirs(path) #多层目录

参考: https://www.cnblogs.com/monsteryang/p/6574550.html

50. 类方法需要增加修饰符

@classmethod

静态方法需要增加修饰符

@staticmethod

静态方法如果要调用静态方法,那么必须显示的写出类名,但是这样不方便后期对类名的修改。所以这时候,建议使用改为类方法来调用静态方法,通过第一个参数 cls 来调用静态方法。

参考: https://stackoverflow.com/questions/1859959/static-methods-how-to-call-a-method-from-another-method https://www.cnblogs.com/mrwuzs/p/10899498.html https://blog.csdn.net/lihao21/article/details/79762681

51. 清空文件夹下的所有文件

import shutil  
shutil.rmtree('要清空的文件夹名')  
os.mkdir('要清空的文件夹名')  

参考: https://blog.csdn.net/Scythe666/article/details/97614113

52. 静态方法中拿到本类的类名,或者调用本类的类变量等等。

TOPIC = "topic"
print(__class__.__name__)
print(__class__.TOPIC)

参考: https://www.codenong.com/510972/

53. 订阅使用 pypubsub 模块,

    def listen(data):
        print("listen data lenght: %d" % len(data))

pub.sendMessage(topic, data = writeData)
pub.subscribe(listen, "recordtest")
pub.unsubscribe(listen, "recordtest")
pub.unsubAll()

参考: https://stackoom.com/question/2TcbQ/%E9%98%B2%E6%AD%A2PyPubSub-%E6%AD%BB%E4%BE%A6%E5%90%AC%E5%99%A8-%E9%94%99%E8%AF%AF https://pypubsub.readthedocs.io/en/v4.0.3/usage/module_pub.html https://pypubsub.readthedocs.io/en/latest/

54. 设置 python 的环境变量,import 的时候这样就不需要写很长的路径, 建立一个类似与这样的脚本,然后通过这个脚本来启动 py 文件。

#!/bin/bash

export TOP_DIR=`pwd`"/../../../"

PYTHONPATH="${PYTHONPATH}:${TOP_DIR}/platform/source/common:${TOP_DIR}/platform/source/speech"

python3 test.py

参考: https://www.cnblogs.com/lifeofershisui/p/8135702.html

55. 使用 syslog 来记录日志

import syslog

syslog.syslog(syslog.LOG_ERR,
                          "[%s:%s] alsaaudio record open exception: %s" %
                          (self.__class__.__name__, sys._getframe().f_code.co_name, e))

注意, 低级别的 log 不会写入到 /var/log/message 里面,比如说 debug 级别,这个就需要用 journalctl 来查看了。正常高级别的 log 需要用命令

sudo tail -fn 100 /var/log/message | grep 感兴趣的字符串

再 journal 中 notice 是加亮显示的。 还有 可以直接 journal 后面加路径,可以看到和这个文件相关的日志。

journalctl /usr/bin/bash

参考: https://www.jianshu.com/p/abb6148c15b4 https://blog.csdn.net/tycoon1988/article/details/38876111 https://www.cnblogs.com/lsdb/p/11132492.html https://cloud.tencent.com/developer/article/1579977 https://blog.csdn.net/zstack_org/article/details/56274966 https://www.howtoing.com/how-to-use-journalctl-to-view-and-manipulate-systemd-logs/ https://www.cnblogs.com/itxdm/p/Systemd_log_system_journalctl.html https://www.digitalocean.com/community/tutorials/how-to-use-journalctl-to-view-and-manipulate-systemd-logs

56. 二进制 bytes() 进行切片可以用

slip = binaryArray[5 : 10]

取第 5 到第 10 之间的数据。

参考: https://www.cnblogs.com/wangchunli-blogs/p/9946961.html

57. 检查子线程是否存在

isAlive( ) 

参考: https://bbs.csdn.net/topics/60074371

58. 类的实例化过程

参考: https://halysl.github.io/2019/06/25/python%E7%B1%BB%E7%9A%84%E5%AE%9A%E4%B9%89%E5%85%A8%E8%BF%87%E7%A8%8B/ https://blog.csdn.net/brucewong0516/article/details/79121179 https://python3-cookbook.readthedocs.io/zh_CN/latest/c09/p19_initializing_class_members_at_definition_time.html

59. 其他的订阅发布

https://ithelp.ithome.com.tw/articles/10227131

60. 自己实现订阅发布

https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p11_implement_publish_subscribe_messaging.html

61. subprocess kill 之后,中断输入没有回显,可以使用命令

stty echo
stty scane

这两种当中一个即可。

参考: https://github.com/pyinvoke/invoke/issues/303 https://stackoverflow.com/questions/6488275/terminal-text-becomes-invisible-after-terminating-subprocess/24780302 http://blog.sina.com.cn/s/blog_64d0b03c0101cwqj.html

62. subprocess 结束,需要使用以下几种方法

sub = subprocess.Popen(...)

sub.kill()
sub.terminate()
sub.send_signal(signal.SIGKILL)
sub.send_signal(signal.SIGTERM)

要注意的是,terminate() 结束的优点是终端不会出问题,缺点是结束比较慢,可以需要 1 秒钟的时间。通过 time.time() 来打印时间戳,获得结束需要的时间。 kill() 结束的优点是立即结束,缺点是 终端输入不能回显,需要随后执行

stty echo
sub = subprocess.Popen("stty echo", shell = True)

这两种的一种才能让终端恢复正常。

参考: https://docs.python.org/zh-cn/3/library/subprocess.html https://www.runoob.com/w3cnote/python3-subprocess.html https://www.liujiangblog.com/course/python/55 https://www.jianshu.com/p/430c411160f8 https://stackoverflow.com/questions/16866602/kill-a-running-subprocess-call https://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true https://www.bogotobogo.com/python/python_subprocess_module.php

63. python 假多线程问题

参考: https://www.cnblogs.com/pengyingh/articles/6586760.html https://zhuanlan.zhihu.com/p/24311810 https://medium.com/@yaoyaowd/python-%E4%BD%A0%E6%80%8E%E4%B9%88%E9%82%A3%E4%B9%88%E6%85%A2-%E7%9C%8B%E7%9C%8B%E5%B9%B6%E8%A1%8C%E5%92%8C%E5%B9%B6%E5%8F%91-6a97c4828d64 https://xwu64.github.io/2019/12/12/Run-Multithread-Python-Program-Parallel/

64. python 检测网络状态

#!/usr/bin/python3

import subprocess

command = "sudo ping -c 1 baidu.com "
back = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
print("back0----", back[0].decode())  # 注意需要进行解码操作,默认输出的是字节
print("back1----", back[1].decode())  # back是一个元祖,可以通过元祖取值的方式获
取结果
print("back1 len", len(back[1].decode()))

如果网络正常, len 数值为 0, 如果不正常,数值为 43 参考: https://blog.csdn.net/gymaisyl/article/details/90746983 https://blog.csdn.net/jinjie412/article/details/51484103 https://blog.csdn.net/Pythonlaowan/article/details/101473072 https://www.jianshu.com/p/28fe223dd624 https://my.oschina.net/u/4305544/blog/3563930 https://ngx.hk/2016/07/16/%E9%80%9A%E8%BF%87ping-%E7%9B%91%E6%B5%8B%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E7%BD%91%E7%BB%9C%E7%8A%B6%E5%86%B5.html http://element-ui.cn/python/show-113985.aspx

65. json 和 python 格式转换

json 转换为 python 的数据类型

json.loads

python 转换为 json

json.dumps

参考: https://www.runoob.com/python/python-json.html https://www.runoob.com/python3/python3-json.html

66. python 返回多个参数 本身其实是返回一个元组,这个元组给这些参数挨个赋值

参考: https://www.cnblogs.com/wllhq/p/8119347.html

67. threads can only be started once 这个是因为线程只能运行一次,所以尽量不要继承 Thread,直接用 Thread 启动线程函数就可以了。

参考: https://blog.csdn.net/yanghuan313/article/details/52985393 https://www.cnblogs.com/i-honey/p/7823587.html

68. os.mkdir(newDir, 0755) 提示 SyntaxError: invalid token,这个是因为 八进制开头需要使用 0o 或者 0O

os.mkdir(newDir, 0O755)

参考: https://blog.csdn.net/JDMXI/article/details/83278978

69. 寻找文件或者文件夹

f searchDir(path, dirName):
    for root, dirs, files in os.walk(path):
        if dirName in dirs:
            return os.path.join(root, dirName)
    return None

参考: https://www.cnblogs.com/Lclkris/p/8724711.html

70. 搜寻指定的内容,使用 grep

    cmd = 'grep -R "import" ' + path
    f = os.popen(cmd)
    data = f.readline()
    f.close()
    print(data)

参考: https://blog.csdn.net/wxliu1989/article/details/24305363

71. 字符串去空格,可以使用 replace 和 strip

lineData = lineData.replace(" ", "").replace("\n", "")

lineData = lineData[start : end].strip()

参考: https://www.php.cn/python-tutorials-414550.html https://blog.csdn.net/jerrygaoling/article/details/81051447 https://www.cnblogs.com/fandx/p/9311755.html

72. 两个列表求 差集,需要借助 set

list1 = list(set(list2) - set(list3))

参考: https://www.cnblogs.com/python-selenium/p/3909175.html https://www.py.cn/faq/python/15193.html https://www.iplaypy.com/jichu/set.html https://blog.csdn.net/suofiya2008/article/details/5591591

73. 显示文件夹目录

os.listdir('./tmp')

参考: https://www.jb51.net/article/164881.htm

74. sort 用于排序,使用 key 参数,可以给列表,字典等排序。使用 sorted 这个函数,返回一个新建的排序后的列表; 如果使用 list 本身的 sort 函数,那么是在原来的列表上进行排序。

self.position[objectName] = (int(scores[i] * 100), 1)   
position = sorted(self.__obj.getPosition().items, key = lambda d : d[1][0], reverse = False)
position = sorted(self.__obj.getPosition(), key = lambda d : d[1], reverse = True)
self.position.append((objectName, int(scores[i] * 100), 1))

参考: https://blog.csdn.net/gymaisyl/article/details/83039279 https://www.cnblogs.com/whaben/p/6495702.html https://www.runoob.com/python/python-func-sorted.html

75. 列表复制,分为以下三种情况

  • 直接复制,相当于直接把地址给了新变量
  • a[:], list(a), a*1, copy.copy(a) 这4种方法,都只是浅复制,最上层列表是真的复制过去了,其中包含的子列表还是给地址
  • copy.deepcopy(a) 这种是深复制,包括子列表,都是真正的复制了一份。

参考: https://www.cnblogs.com/ifantastic/p/3811145.html

76. RuntimeError: dictionary changed size during iteration. 解决方法是把 key 先生成列表。

错误用法:

for k in func_dict.keys():
    if func_dict[k] is np.nan:
        del func_dict[k]
        continue

正确用法:

for k in list(func_dict.keys()):
    if func_dict[k] is np.nan:
        del func_dict[k]
        continue

参考: https://blog.csdn.net/u013344884/article/details/81867225

77. python3 -m venv v2 报错 Command '['/home/fmr/projects/ave/venv/bin/python3.4', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1

这个是因为没有安装 python3-venv

apt install python3-venv

参考: https://askubuntu.com/questions/1268833/error-command-path-to-env-bin-python3-7-im-ensurepip-upgrade https://github.com/pypa/virtualenv/issues/1059 https://stackoverflow.com/questions/24123150/pyvenv-3-4-returned-non-zero-exit-status-1

78. zip() 可以把 两个可迭代对象打包成一个个元组。然后返回这些元组组成的对象。 zip([iterable, ...])

a = [1, 2, 3]
b = [4, 5, 6]
c = list(zip(a, b))
# c: [(1, 4), (2, 5), (3, 6)]

参考: https://www.runoob.com/python3/python3-func-zip.html

79. map() 用于对可迭代对象通过函数进行计算,返回计算结果的迭代器,一般和 list() 搭配使用。 map(function, iterable, ...)

def square(x) :
  return x ** 2

list(map(square, [1,2,3,4,5]))

参考: https://www.runoob.com/python3/python3-func-map.html

80. lambda 匿名函数,: 前面的是参数列表, : 后面的是计算式子。 lambda [arg1 [,arg2,.....argn]]:expression

sum = lambda arg1, arg2: arg1 + arg2

参考: https://www.runoob.com/python3/python3-function.html

81. reduce() 用于对一个可迭代的对象进行函数操作,并把计算结果和下一个迭代器进行计算,直到计算完成。

reduce(function, sequence [, initial] ) -> value function参数是一个有两个参数的函数,reduce依次从sequence中取一个元素,和上一次调用function的结果做参数再次调用function。 第一次调用function时,如果提供initial参数,会以sequence中的第一个元素和initial作为参数调用function,否则会以序列sequence中的前两个元素做参数调用function。

from functools import reduce
lst=[1,2,3,4]
print(reduce(lambda x,y: x*y, lst))

# 结果24

lst=[1,2,3,4]
print(reduce(lambda x,y: x+y, lst,5))

# 5是初始值,也可以理解为第三个参数
# 计算呢过程
-->5+1=6
-->6+2=8
-->8+3=11
-->11+4=15

参考: https://www.cnblogs.com/apollo1616/articles/9785335.html

82. RuntimeError: matplotlib does not support generators as input ,这个报错是因为 python2 中 map 返回的是列表, python3 中 map 返回的是 迭代器, matplotlib 中的参数不能是迭代器,所以报错。简单的解决方法是在 map 外面增加一层 list 即可。

ax.scatter(map(lambda x: x[0], input_vecs), labels)          # error
ax.scatter(list(map(lambda x: x[0], input_vecs)), labels)    # correct

参考: https://www.runoob.com/python/python-func-map.html https://blog.csdn.net/explorer9607/article/details/81879697

83. 多进程通信使用 Queue 或者 pipe。pipe 只能用于两个进程之间的通信,Queue 可以用于多个进程之间通信。但是注意 Queue 有两种,一个是进程安全,数据只能被读一次,一个是进程不安全,数据可以被读多次。

# 进程不安全
import Queue
# 进程安全
from multiprocessing import Queue

参考:https://www.jianshu.com/p/a4de38b8c68d

84. 'NoneType' object is not iterable 这个错误是说,默认的返回值是 None,如果 return 的是多个值,那么就会报这个错。正常出现这种情况是函数里面在 if 中 return,但是没有在所有情况下 return,所以出现有一种情况没有明确的 return,这样就导致不能把一个 None 返回给多个值。

参考:https://blog.csdn.net/qq_42780289/article/details/96971940

85. 多进程,可以直接用 multiprocess 中的 process 来创建,也可以使用进程池。 如果进程数是确定的,并且进程从前到后工作,这样就适合使用 process 来创建;如果进程数目是不确定的,只是临时起一个线程来处理任务,处理完了就结束,这样的适合使用线程池。

参考: https://blog.csdn.net/qq_33567641/article/details/81947832 https://www.cnblogs.com/kaituorensheng/p/4445418.html

86. 进程结束的返回值可以通过回调函数来处理。

#!/usr/bin/python3

import time, os
import requests
from concurrent.futures import ProcessPoolExecutor

def get(url):
    print('%s GET %s' % (os.getpid(), url))
    time.sleep(3)
    response = requests.get(url)
    if response.status_code == 200:
        res = response.text
    else:
        res = '下载失败'
    return res

def parse(future):
    time.sleep(1)
    # 传入的是个对象,获取返回值 需要进行result操作
    res = future.result()
    print("res",)
    print('%s 解析结果为%s' % (os.getpid(), len(res)))

if __name__ == '__main__':
    urls = [
        'https://www.baidu.com',
        'https://www.sina.com.cn',
        'https://www.tmall.com',
        'https://www.jd.com',
        'https://www.python.org',
        'https://www.openstack.org',
        'https://www.baidu.com',
        'https://www.baidu.com',
        'https://www.baidu.com',
    ]
    p = ProcessPoolExecutor(9)
    start = time.time()
    for url in urls:
        future = p.submit(get,url)
        #模块内的回调函数方法,parse会使用future对象的返回值,对象返回值是执行任
务的返回值
        #回调应该是相当于parse(future)
        future.add_done_callback(parse)

    p.shutdown(wait=True)
    print("完成时间",time.time()-start)#完成时间 33.79998469352722

参考:https://www.cnblogs.com/venvive/p/11601190.html

87. 使用管道的时候,不需要的端就及时关掉。比如说子进程写,父进程读,那么在 start 之后,父进程就应该关掉写端,这样当子进程结束的时候,父进程中的阻塞读就可以通过 EOFError 的异常退出来。特别是父进程中如果是用线程去读的话,就一定要这样处理,负责读去线程会因为阻塞退不出来。

#!/usr/bin/python3

import time, threading, datetime
from multiprocessing import Process, Pipe

from esp_gpio import *

class EspUltrasonic:
    def __init__(self, hook = None):
        self.__thread = None
        self.__eStop = True
        self.__hook = hook
        self.__dist = -1
        self.__process = None
        self.__pipeW = None
        self.__pipeR = None

    def __usrProcess(self, pipeW):
        while True:
            ret, dist = self.__getDistance()
            pipeW.send(self.__dist)
            time.sleep(0.1)
        pipeW.close()
        print("ultrasonic process over")

    def __usrRun(self):
        while self.__eStop == False:
            try:
                self.__dist = self.__pipeR.recv()
                #print("process dist: ", self.__dist)
            except EOFError as e:
                print(e)
                break
            #time.sleep(1)
        print("ultrasonic thread over")

    def getDist(self):
        return self.__dist

    def start(self):
        print("ultrasonic thread start")
        if self.__eStop == False:
            return

        #self.__thread = threading.Thread(target = self.__usrRun)
        self.__eStop = False
        self.__pipeR, self.__pipeW = Pipe()
        self.__process = Process(target = self.__usrProcess, args = (self.__pipeW,))
        self.__process.start()
        self.__pipeW.close()

        self.__thread = threading.Thread(target = self.__usrRun)
        self.__thread.start()

    def stop(self):
        print("ultrasonic stop")
        if self.__eStop == True:
            return

        self.__eStop = True
        self.__process.terminate()
        self.__process.join()
        self.__pipeR.close()
        self.__thread.join()

if __name__ == "__main__":
    def printTest(data):
        print("usr hook test: ", data)

    ul = EspUltrasonic(hook = printTest)

    ul.start()
    time.sleep(10)
    ul.stop()

参考: https://stackoverflow.com/questions/24799869/closing-pipe-in-python

82. 进程间数据通信,如果数据量比较少,只是用于控制作用,那么可以使用共享内存或者 manager(),manager() 支持的类型比较多。需要注意的是 Value 类型和其他类型不一样。其他类型可以直接使用,而 Value 类型是对基本类型的封装,所以不能直接使用,使用的时候,使用 .value 这样的方法来改变数值。

#!/usr/bin/python3

import threading
from multiprocessing import Process, Manager

class testf:
    def __init__(self):
        self.manager = Manager()
        self.d = self.manager.dict()
        self.l = self.manager.list(range(10))
        self.v = self.manager.Value('i', 0)
        self.p = None
        self.thread = None

    def f(self, d, l, v):
        d[1] = '1'
        d['2'] = 2
        d[0.25] = None
        l.reverse()
        v.value = 1

    def strun(self):
        self.v.value = 0
        self.p = Process(target=self.f, args=(self.d, self.l, self.v))
        self.p.start()
        self.p.join()

        print(self.d)
        print(self.l)
        print(self.v.value)

    def st(self):
        self.thread = threading.Thread(target = self.strun)
        self.thread.start()
        self.thread.join()

if __name__ == '__main__':
    tf = testf()
    tf.st()

参考:https://blog.csdn.net/lechunluo3/article/details/79005910 https://docs.python.org/zh-cn/3/library/multiprocessing.html#multiprocessing.Queue https://docs.python.org/zh-cn/3/library/array.html#module-array

83. 多进程可以有多种方式,他们各有特点。

  1. Process, 功能最多最通用, 可以强制结束,可以有共享数据,可以用 pipe, queue 等等。但是没有退出状态。
  2. ProcessPoolExecutor,这种池,不好的地方是,不能从外界结束正常运行的进程。
  3. subprocess,这个有退出状态返回,但是没有 pipe, queue 之类的。 参考: https://docs.python.org/zh-cn/3/library/concurrency.html https://www.cnblogs.com/whatisfantasy/p/6440585.html

84. @property 这个装饰器可以让类外面直接使用类内的成员变量,同时对成员变量的具体数值受到类内的成员函数限制。

class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2015 - self._birth

还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性,上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208 https://segmentfault.com/q/1010000014834657

85. 函数定义的时候,右边有个 -> int 这个是用来描述函数的返回类型。

def add(x:int, y:int) -> int:
    return x + y

python解释器不会对这些注解添加任何的语义。它们不会被类型检查,运行时跟没有加注解之前的效果也没有任何差距。 然而,对于那些阅读源码的人来讲就很有帮助啦。第三方工具和框架可能会对这些注解添加语义。同时它们也会出现在文档中。

>>> help(add)
Help on function add in module __main__:
add(x: int, y: int) -> int
>>>

参考: https://python3-cookbook.readthedocs.io/zh_CN/latest/c07/p03_attach_informatinal_matadata_to_function_arguments.html https://python3-cookbook.readthedocs.io/zh_CN/latest/c07/p03_attach_informatinal_matadata_to_function_arguments.html

86 argsort()

argsort 主要是用来返回一个数组的元素从小到大排列时,索引组成的数组。

import numpy as np
x=np.array([1,4,3,-1,6,9])
x.argsort()

输出为 array([3,0,2,1,4,5])

参考: https://www.cnblogs.com/yyxf1413/p/6253995.html

87 str.rstrip([chars])

删除字符串末尾的指定字符,如果不指定默认删除空格。

str = "     this is string example....wow!!!     ";
print str.rstrip();
str = "88888888this is string example....wow!!!8888888";
print str.rstrip('8');

参考: https://www.runoob.com/python/att-string-rstrip.html

参考数目:

python3 cook-book,讲解的很全面。 https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p08_perform_simple_parallel_programming.html

标签: python

添加新评论