basic

static-method

python 中并没有像是 Java 里的 static 关键字,取代的是 @classmethod@staticmethod

class A:

name = 'A'

# 至少有一个隐式形参 (本类 cls 对象), 可以访问类属性
@classmethod
def a(cls):
print(cls.name)

# 无形参, 也就是说拿不到类属性
@staticmethod
def b():
print('b')


A.a()
A.b()
A
b

multi-condition

if(a||b)当 a 为真时,还会对 b 求值吗?

不会

import time


def calculate(name, t):
print("calculating: ", name, "seconds needs: ", t)
time.sleep(t)
return True


if (calculate('A', 2) or calculate('B', 2)):
print("Done")

calculating:  A seconds needs:  2
Done

下划线

教程来自: [4]

_

# 单个 _ 指向最后一次执行表达式 (结果)
# 在 python 命令行中可以跑, 在这里不行
# 1 + 2
# _

# 格式化数字
print(114_514_1919_810)

# 类似 golang 的遍历
for _ in range(10):
print(_)
1145141919810
0
1
2
3
4
5
6
7
8
9

__xxx__

魔术方法 / 魔法函数, 一般作为内置方法

import random

random.__name__
'random'

_xxx

私有化, 仅提供模块内部调用, 类似Java里的 protect

__xxx

也是私有化, 类似 Java 内的 private, 无法直接访问此变量/方法, 但可以间接访问

class Person:
def __init__(self, name, age):
self.name = name
self.__age = age

def get_age(self):
return self.__age


me = Person('张三', 18)

print(me.name)

# print(me.age)
# print(me.__age)
# 上面两种都会报错, __age -> _Person__age
print(me._Person__age)
print(me.get_age())

print(dir(me))
张三
18
18
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_age', 'name']

_xxx__xxx

从上面例子可以看到, 能通过这个访问类私有化属性

you = Person('李四', 20)
you._Person__age += 1
print(you.get_age())
21

xxx_

类似转义, 让某些关键词无效化

max_ = max(1, 2, 3)
print(max_)
3

闭包

听起来挺抽象的, 下面这个例子实现的静态代理的功能, 只不过这种通过函数包裹函数并且回传函数的形式称为闭包

def func_1(func):
def wrapper():
print(f'{func} running')
func()
print(f'{func} finished')

return wrapper


my_func = func_1(lambda: print('hello'))
my_func()
<function <lambda> at 0x000002C6132A50D0> running
hello
<function <lambda> at 0x000002C6132A50D0> finished
def login_user(username, password):
print('login success')


def check(func):
# 这里的 argv 可以直接获取 func 的
def wrapper(username, password):
if username == 'user' and password == 'password':
return func(username, password)
else:
print('login failed')

return wrapper


login_user = check(login_user)
login_user('user', 'password')
login success

装饰器

decorator-@, 从Java里叫注解, 上面的例子可写成下面这样

@check
def login_user(username, password):
print('login success')


def check(func):
# 这里的 argv 可以直接获取 func 的
def wrapper(username, password):
if username == 'user' and password == 'password':
return func(username, password)
else:
print('login failed')

return wrapper


login_user('user', 'password')
login success

modules

base64

import base64

username = 'Weidows'
password = '123456'

encode = base64.b64encode((username + ":" + password).encode())
# Basic V2VpZG93czoxMjM0NTY==
headers = {"Authorization": "Basic " + encode.decode()}

print(headers)
{'Authorization': 'Basic V2VpZG93czoxMjM0NTY='}

多线程-进程

Python 多线程不能利用 CPU 多核优势,IO 密集型可用多线程,CPU 密集型适合用多进程 [2]

也就是说只有 IO 密集型任务适用多线程,其他情况: 多进程 > 不用 > 多线程, API 区别如下:[3]

R9zQZh.png

虽然但是,很多情况下涉及到资源共享, 多进程处理起来比较麻烦,还是多线程舒服.

from concurrent.futures import ThreadPoolExecutor
import threading
import multiprocessing
import time

multi_num = multiprocessing.cpu_count() * 2

def counter(num):
time.sleep(num)
print(threading.currentThread().name, num, end='\t')


if __name__ == '__main__':
with ThreadPoolExecutor(max_workers=multi_num) as thread_pool:
start = time.time()
thread_pool.map(counter, range(10))

# 等待任务执行完再跳回 main
thread_pool.shutdown(wait=True)
print("多线程: ", time.time() - start)
ThreadPoolExecutor-0_0 0	ThreadPoolExecutor-0_1 1	ThreadPoolExecutor-0_0 2	ThreadPoolExecutor-0_2 3	ThreadPoolExecutor-0_3 4	ThreadPoolExecutor-0_4 5	ThreadPoolExecutor-0_5 6	ThreadPoolExecutor-0_6 7	ThreadPoolExecutor-0_7 8	ThreadPoolExecutor-0_8 9	多线程:  9.009207010269165

opengl

彩色三角形

# -------------------------------------------
# quidam_01.py 三维空间的世界坐标系和三角形
# -------------------------------------------

from OpenGL.GL import *
from OpenGL.GLUT import *


def draw():
# ---------------------------------------------------------------
glBegin(GL_LINES) # 开始绘制线段(世界坐标系)

# 以红色绘制x轴
glColor4f(1.0, 0.0, 0.0, 1.0) # 设置当前颜色为红色不透明
glVertex3f(-0.8, 0.0, 0.0) # 设置x轴顶点(x轴负方向)
glVertex3f(0.8, 0.0, 0.0) # 设置x轴顶点(x轴正方向)

# 以绿色绘制y轴
glColor4f(0.0, 1.0, 0.0, 1.0) # 设置当前颜色为绿色不透明
glVertex3f(0.0, -0.8, 0.0) # 设置y轴顶点(y轴负方向)
glVertex3f(0.0, 0.8, 0.0) # 设置y轴顶点(y轴正方向)

# 以蓝色绘制z轴
glColor4f(0.0, 0.0, 1.0, 1.0) # 设置当前颜色为蓝色不透明
glVertex3f(0.0, 0.0, -0.8) # 设置z轴顶点(z轴负方向)
glVertex3f(0.0, 0.0, 0.8) # 设置z轴顶点(z轴正方向)

glEnd() # 结束绘制线段

# ---------------------------------------------------------------
glBegin(GL_TRIANGLES) # 开始绘制三角形(z轴负半区)

glColor4f(1.0, 0.0, 0.0, 1.0) # 设置当前颜色为红色不透明
glVertex3f(-0.5, -0.366, -0.5) # 设置三角形顶点
glColor4f(0.0, 1.0, 0.0, 1.0) # 设置当前颜色为绿色不透明
glVertex3f(0.5, -0.366, -0.5) # 设置三角形顶点
glColor4f(0.0, 0.0, 1.0, 1.0) # 设置当前颜色为蓝色不透明
glVertex3f(0.0, 0.5, -0.5) # 设置三角形顶点

glEnd() # 结束绘制三角形

# ---------------------------------------------------------------
glFlush() # 清空缓冲区,将指令送往硬件立即执行


if __name__ == "__main__":
glutInit() # 1. 初始化glut库
glutCreateWindow('Quidam Of OpenGL') # 2. 创建glut窗口
glutDisplayFunc(draw) # 3. 注册回调函数draw()
glutMainLoop() # 4. 进入glut主循环

点线抛物线

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from numpy import *
import sys


def init():
glClearColor(1.0, 1.0, 1.0, 1.0)
gluOrtho2D(-5.0, 5.0, -5.0, 5.0)


def plotfunc():
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(1.0, 0.2, 0.6)
glPointSize(3.0)

glBegin(GL_POINTS)
for x in arange(-5.0, 5.0, 0.1): #from -5.0 to 5.0 plus 0.1 every time
y = x * x
glVertex2f(x, y)
glEnd()
glFlush()


def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowPosition(50, 100)
glutInitWindowSize(400, 400)
glutCreateWindow("Function Plotter")
glutDisplayFunc(plotfunc)

init()
glutMainLoop()


main()

转动时钟

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import math
import time

h = 0
m = 0
s = 0


def Draw():
PI = 3.1415926
R = 0.5
TR = R - 0.05
glClear(GL_COLOR_BUFFER_BIT)
glLineWidth(5)
glBegin(GL_LINE_LOOP)
for i in range(100):
glVertex2f(R * math.cos(2 * PI / 100 * i),
R * math.sin(2 * PI / 100 * i))
glEnd()
glLineWidth(2)
for i in range(100):
glBegin(GL_LINES)
glVertex2f(TR * math.sin(2 * PI / 12 * i),
TR * math.cos(2 * PI / 12 * i))
glVertex2f(R * math.sin(2 * PI / 12 * i),
R * math.cos(2 * PI / 12 * i))
glEnd()
glLineWidth(1)

h_Length = 0.2
m_Length = 0.3
s_Length = 0.4
count = 60.0
s_Angle = s / count
count *= 60
m_Angle = (m * 60 + s) / count
count *= 12
h_Angle = (h * 60 * 60 + m * 60 + s) / count
glLineWidth(1)
glBegin(GL_LINES)
glVertex2f(0.0, 0.0)
glVertex2f(s_Length * math.sin(2 * PI * s_Angle),
s_Length * math.cos(2 * PI * s_Angle))
glEnd()
glLineWidth(5)
glBegin(GL_LINES)
glVertex2f(0.0, 0.0)
glVertex2f(h_Length * math.sin(2 * PI * h_Angle),
h_Length * math.cos(2 * PI * h_Angle))
glEnd()
glLineWidth(3)
glBegin(GL_LINES)
glVertex2f(0.0, 0.0)
glVertex2f(m_Length * math.sin(2 * PI * m_Angle),
m_Length * math.cos(2 * PI * m_Angle))
glEnd()
glLineWidth(1)
glBegin(GL_POLYGON)
for i in range(100):
glVertex2f(0.03 * math.cos(2 * PI / 100 * i),
0.03 * math.sin(2 * PI / 100 * i))
glEnd()
glFlush()


def Update():
global h, m, s
t = time.localtime(time.time())
h = int(time.strftime('%H', t))
m = int(time.strftime('%M', t))
s = int(time.strftime('%S', t))
glutPostRedisplay()


glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(400, 400)
glutCreateWindow("My clock")
glutDisplayFunc(Draw)
glutIdleFunc(Update)
glutMainLoop()

Hello-World-pyglet

import pyglet

window = pyglet.window.Window()

label = pyglet.text.Label('Hello, world',
font_name='Times New Roman',
font_size=36,
x=window.width // 2,
y=window.height // 2,
anchor_x='center',
anchor_y='center')


@window.event
def on_draw():
window.clear()
label.draw()


pyglet.app.run()

茶壶

动态

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


def drawFunc():
#清楚之前画面
glClear(GL_COLOR_BUFFER_BIT)
glRotatef(0.1, 5, 5, 0) #(角度,x,y,z)
glutWireTeapot(0.5)
#刷新显示
glFlush()


#使用glut初始化OpenGL
glutInit()
#显示模式:GLUT_SINGLE无缓冲直接显示|GLUT_RGBA采用RGB(A非alpha)
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
#窗口位置及大小-生成
glutInitWindowPosition(0, 0)
glutInitWindowSize(400, 400)
glutCreateWindow(b"first")
#调用函数绘制图像
glutDisplayFunc(drawFunc)
glutIdleFunc(drawFunc)
#主循环
glutMainLoop()

静态

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


def drawFunc():
glClear(GL_COLOR_BUFFER_BIT)
# 设置为红色
glColor3f(1.0, 0.0, 0.0)
glutWireTeapot(0.5)
glFlush()


glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(400, 400)

#参数为b类型而不是string
glutCreateWindow(b"Teapot")
glutDisplayFunc(drawFunc)
glutMainLoop()

数据分析

numpy

newaxis

import numpy as np

A = np.array([[2, 0, 2, 1], [2, 0, 2, 2]])

print(A)
print("A.shape: ", A.shape)

# new 一个一维数组,然后把 A 整个怼进去
B = A[np.newaxis, :]
print(B)
print("B.shape: ", B.shape)

C = A[:, np.newaxis]
print(C)
print("C.shape: ", C.shape)

# 把每个第二维第四位的元素怼进一个新数组,把原第二位替换为此新数组
D = A[:, np.newaxis, 3]
print(D)
print("D.shape: ", D.shape)

[[2 0 2 1]
 [2 0 2 2]]
A.shape:  (2, 4)
[[[2 0 2 1]
  [2 0 2 2]]]
B.shape:  (1, 2, 4)
[[[2 0 2 1]]

 [[2 0 2 2]]]
C.shape:  (2, 1, 4)
[[1]
 [2]]
D.shape:  (2, 1)

Matplotlib

figure

可以用 figure 对输出的图片进行缩放

import matplotlib.pyplot as plt

plt.imshow(plt.imread('./_data_set/kitti_000008_pred.png'))
<matplotlib.image.AxesImage at 0x22c4640aa90>

png

import matplotlib.pyplot as plt

plt.figure(figsize=(25, 20))
plt.imshow(plt.imread('./_data_set/kitti_000008_pred.png'))
<matplotlib.image.AxesImage at 0x22c4651a1c0>

png

分割线

借物表

[1]: How does numpy.newaxis work and when to use it?

[2]: Python threadpool与multiprocessing

[3]: Python并发实战,怎样使用多进程multiprocessing加速程序运行

[4]: Python 中各种下划线的骚操作:_、xx、xx、__xx、xx、_classname__xx