Python
装饰器 decorator¶
@
能在最小改变函数的情况下,包装新的功能。1
def use_logging(func):
def wrapper():
logging.warn("%s is running" % func.__name__)
return func()
return wrapper
@use_logging
def foo():
print("i am foo")
foo()
Programming Specification¶
- 命名空间(namespace)可以基本理解成每个文件是一个,通过
import
来使用
if name == "main"¶
在Python中,if __name__ == "__main__"
这种写法通常出现在模块中,它的作用是控制模块的执行流程。
当一个模块被导入时,Python解释器会自动将这个模块的__name__属性设置为模块名称。但是如果模块是被直接运行的,则__name__属性会被设置为字符串__main__。
所以if name == "main"可以用来区分模块是被导入运行还是被直接运行:
如果模块是被导入的,if语句不会执行。因为模块的__name__不等于__main__。 如果模块是被直接运行的,if语句会执行。因为模块的__name__等于__main__。
单下划线、双下划线、头尾双下划线说明:¶
__foo__
: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
_foo
: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo
: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
数据快速写入和读取文件¶
任意变量使用pickle
# 使用二进制
with open('my_dict.json', 'wb') as f:
pickle.dump(my_dict, f)
with open('my_dict.json', 'rb') as f:
loaded_dict = pickle.load(f)
可以序列化的使用json
import json
# 将 dict 保存为 JSON 格式
with open('my_dict.json', 'w') as f:
json.dump(my_dict, f)
# 加载 dict
with open('my_dict.json', 'r') as f:
loaded_dict = json.load(f)
多个变量
# 将多个变量组织成字典或列表
data = {
"scaAvgTime": scaAvgTime,
"var2": var2,
"var3": var3
}
result_file = "result.json"
# 将数据写入JSON文件
with open(result_file, "w") as f:
json.dump(data, f)
# 读取JSON文件
with open(result_file, "r") as f:
data = json.load(f)
# 获取保存的变量值
scaAvgTime = data["scaAvgTime"]
var2 = data["var2"]
var3 = data["var3"]
python优化 可视化¶
cProfile + snakeviz + gprof2dot
https://github.com/plasma-umass/scalene
reference¶
https://github.com/jrfonseca/gprof2dot
https://zhuanlan.zhihu.com/p/58535923
https://www.cnblogs.com/oloroso/p/6548189.html
Debug¶
打印当前堆栈¶
traceback.print_stack()
icecream for debug¶
- 优雅打印对象:函数名,结构体
- 打印行号和栈(没用输入时
- 允许嵌套(会将输入传递到输出
- 允许带颜色
ic.format(*args)
获得ic打印的文本 - debug
ic.disable()
andic.enable()
- 允许统一前缀
ic.configureOutput(prefix='Debug | ')
- 不用每个文件import
from icecream import ic
ic(STH)
from icecream import install
install()
ic.configureOutput(prefix='Debug -> ', outputFunction=yellowPrint)
prefix 添加时间
hide message
ic()的输出无法被tee的log文件捕获
这个问题与 icecream
库的 ic()
函数的默认输出机制有关。icecream
默认将输出发送到标准错误(stderr
),而 tee
命令的默认行为是只捕获标准输出(stdout
)。因此,ic()
的输出不会被 tee
捕获到。
要解决这个问题,你可以采取以下几种方式:
- 使用
ic()
输出到标准输出 - 你可以配置
icecream
的输出流,使其输出到标准输出,而不是默认的标准错误。这样,tee
就可以捕获ic()
的输出。
这样,ic()
的输出就会被发送到标准输出,然后可以被 tee
命令捕获到。
- 让
tee
捕获标准错误和标准输出
你也可以让 tee
捕获标准错误(stderr
)和标准输出(stdout
),这样无需修改 icecream
的配置。
在你的命令中,可以使用如下方式:
在这个命令中,2>&1
将标准错误重定向到标准输出,因此 tee
可以同时捕获两者。
- 使用
tee
捕获标准错误单独输出
如果你只想捕获标准错误的输出,并将其保存到日志文件,可以使用以下命令:
或将 stderr
和 stdout
单独重定向:
虚拟环境venv¶
python3 -m venv name
#在Windows上,运行:
name\Scripts\activate.bat # poweshell运行activate.ps1
#在Unix或MacOS上,运行:
source name/bin/activate
#(这个脚本是为bash shell编写的。如果你使用 csh 或 fish shell,你应该改用 activate.csh 或 activate.fish 脚本。)
python3 setup.py install
各种依赖¶
pip换源¶
有时候开代理会出现Retry
vim ~/.pip/pip.conf
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
pip config set global.trusted-host pypi.mirrors.ustc.edu.cn
pip install --trusted-host mirrors.bfsu.edu.cn icecream
python的实现过的各种功能模块¶
并行调用shell命令,超时kill¶
https://github.com/Kirrito-k423/BHive-Prediction-Compare/blob/main/pythonTest/0326_newBar_qcjiang.py
基于Pipe的自定义多进程进度条¶
https://github.com/Kirrito-k423/BHive-Prediction-Compare/blob/main/pythonTest/0326_newBar_qcjiang.py
为什么c语言运行比python快¶
运行流程区别¶
python的传统运行执行模式:录入的源代码转换为字节码,之后字节码在python虚拟机中运行。代码自动被编译,之后再解释成机器码在CPU中执行。
c编译器直接把c源代码编译成机器码。过程比python执行过程少了字节码生成和虚拟机执行字节码过程。所以自然比python快。
解释性语言¶
解释型语言没有严格编译汇编过程,由解释器将代码块按需要变运行边翻译给机器执行。因此解释型语言一度存在运行效率底,重复解释的问题。但是通过对解释器的优化!可以提高解释型语言的运行效率。
Python 字节码¶
Python 以 .pyc 结尾的 “ 字节码(bytecode)” 文件(二进制文件),一般位于__pycache__ 的子目录中,可以避免每次运行 Python 时去重新解析源代码。
python程序运行中的 Python 字节码 是什么时候产生的,我修改py文件,其对应的字节码文件会在何时更新¶
gpt3.5: Python字节码是由Python解释器在执行Python源代码之前生成的中间表示形式。它是将源代码翻译为机器可以理解的指令序列的一种形式。字节码文件的扩展名通常为.pyc(Python 3)或.pyo(Python 2)。
当你运行Python程序时,如果存在对应的字节码文件(.pyc或.pyo),解释器会首先检查字节码文件的时间戳。如果字节码文件的时间戳比源代码文件的时间戳更晚,且没有进行代码的修改,解释器会直接加载和执行字节码,跳过源代码的编译过程。
当你修改了Python源代码文件时,字节码文件不会立即更新。Python解释器会在下一次运行程序时,检测到源代码文件的修改,并重新编译生成新的字节码文件。这样,更新后的字节码文件将反映源代码的更改,并用于后续的执行。
访问和理解 Python 字节码¶
经过编译的python文件可以提高程序的运行速度,一定程度上也对源代码起到了保护作用。然而如果我们只有编译过的python字节码文件,就给我们审查源码造成了一定的困难,这就引出了python字节码反编译的需求。
如果你想玩转字节码,那么,Python 标准库中的 dis 模块将对你有非常大的帮助;dis 模块为 Python 字节码提供了一个 “反汇编”,它可以让你更容易地得到一个人类可读的版本,以及查找各种字节码指令。
知道如何去访问和阅读 Python 字节码将让你很容易回答为什么某些结构比其它结构运行的更快这样的问题(比如,为什么 {} 比 dict() 快)(尝试对比一下: dis.dis("{}") 与 dis.dis("dict()") 就会明白)。
pyo优化文件¶
pyo文件是源代码文件经过优化编译后生成的文件,是pyc文件的优化版本。编译时需要使用-O和-OO选项来生成pyo文件。在Python3.5之后,不再使用.pyo文件名,而是生成文件名类似“test.opt-n.pyc的文件。
Python 虚拟机¶
CPython 使用一个基于栈的虚拟机。(你可以 “推入” 一个东西到栈 “顶”,或者,从栈 “顶” 上 “弹出” 一个东西来)。
CPython 使用三种类型的栈:
- 调用栈(call stack)。这是运行 Python 程序的主要结构。它为每个当前活动的函数调用使用了一个东西 —— “ 帧(frame)”
- 在每个帧中,有一个 计算栈(evaluation stack)(也称为 数据栈(data stack))。这个栈就是 Python 函数运行的地方,运行的 Python 代码大多数是由推入到这个栈中的东西组成的,操作它们,然后在返回后销毁它们。
- 在每个帧中,还有一个块栈(block stack)。它被 Python 用于去跟踪某些类型的控制结构:循环、try / except 块、以及 with 块,全部推入到块栈中,当你退出这些控制结构时,块栈被销毁。
Python 如何工作¶
Python 与大多数解释型语言一样,确实是将源代码编译为一组虚拟机指令,并且 Python 解释器是针对相应的虚拟机实现的。这种中间格式被称为 “字节码”。
需要进一步的研究学习¶
暂无
遇到的问题¶
暂无
开题缘由、总结、反思、吐槽~~¶
在了解c语言编译流程的时候,联想到了python有什么不同。
参考文献¶
https://zhuanlan.zhihu.com/p/39259061