跳至主要內容
装饰器与注册器

当你的项目中需要成批量的函数和类,且这些函数和类功能上相似或并行时,为了方便管理,你可以把这些指定的函数和类整合到一个字典,你可以用函数名或类名作为字典的key,也可用使用自定义的名字作为key,对应的函数或类作为value。构建这样一个字典的过程就是注册,Python引入注册器机制保证了这个字典可以自动维护,增加或删除新的函数或类时,不需要手动去修改字典。

Python注册器机制本质上是用装饰器来实现的。下面将从基本的Python函数出发,逐步介绍装饰器,最后学习注册器。

python函数

首先定义一个函数,然后用不同的方式调用它:


Genhiy...大约 13 分钟PythonCodeBook
AI Code Book

onehot编码:np.eye()

np.eye():函数的原型:numpy.eye(N,M=None,k=0,dtype=<class ‘float’>,order=‘C)

返回的是一个二维2的数组(N,M),对角线的地方为1,其余的地方为0.

  • N:int型,表示的是输出的行数
  • M:int型,可选项,输出的列数,如果没有就默认为N
  • k:int型,可选项,对角线的下标,默认为0表示的是主对角线,负数表示的是低对角,正数表示的是高对角。
  • dtype:数据的类型,可选项,返回的数据的数据类型
  • order:{‘C’,‘F’},可选项,也就是输出的数组的形式是按照C语言的行优先’C’,还是按照Fortran形式的列优先‘F’存储在内存中。

Genhiy...大约 1 分钟PythonCodeBook
Python partial

今天介绍一下 Python 中的偏函数(functools.partial)

首先,我们需要简单了解下偏函数的作用:和装饰器一样,它可以扩展函数的功能,但又不完成等价于装饰器。通常应用的场景是当我们要频繁调用某个函数时,其中某些参数是已知的固定值,通常我们可以调用这个函数多次,但这样看上去似乎代码有些冗余,而偏函数的出现就是为了很少的解决这一个问题。举一个很简单的例子,比如我就想知道 100 加任意数的和是多少,通常我们的实现方式是这样的:

# 第一种做法:
def add(*args):
    return sum(args)

print(add(1, 2, 3) + 100)
print(add(5, 5, 5) + 100)

# 第二种做法
def add(*args):
    # 对传入的数值相加后,再加上100返回
    return sum(args) + 100

print(add(1, 2, 3))  # 106
print(add(5, 5, 5))  # 115 

Genhiy...大约 4 分钟PythonCodeBook
Python codebook

数据结构和算法

global 和 nonlocal

第一,两者的功能不同。global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。

第二,两者使用的范围不同。global关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global修饰后也可以直接使用,而nonlocal关键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误(见第一)。


Genhiy...大约 33 分钟PythonCodeBook
Torch

tensor

zeros()、ones()

创建全0、全1的tensor:

>>> torch.zeros([2, 4], dtype=torch.int32)
tensor([[ 0,  0,  0,  0],
        [ 0,  0,  0,  0]], dtype=torch.int32)
>>> cuda0 = torch.device('cuda:0')
>>> torch.ones([2, 4], dtype=torch.float64, device=cuda0)
tensor([[ 1.0000,  1.0000,  1.0000,  1.0000],
        [ 1.0000,  1.0000,  1.0000,  1.0000]], dtype=torch.float64, device='cuda:0')

Genhiy...大约 15 分钟PythonCodeBook
PythonLibs

pip提供了一个选项 --no-dependencies ,用于指定不安装包的依赖项。 通过使用这个选项,我们可以强制pip只安装指定的包,而不检查和安装依赖关系。

调试相关库

pdb库

使用方法:在代码中添加'import pdb;pdb.set_trace()',当你在命令行看到(Pdb)时,说明已经正确打开了pdb,然后就可以开始输入pdb命令了。

常用命令:

  • l (list): 查看当前位置前后11行源代码(多次会翻页); ll: 查看当前函数或框架内的所有代码。
  • s (step): 执行下一行(能进入函数体); n (next): 执行下一行(不进入函数体); r (return): 执行下一行(在函数体中时会直接执行到函数返回处)。
  • p: 后跟变量,表示打印该变量值。
  • cl: 不带参数用于清除所有断点,带参数则清除指定行或当前文件制定序号的断点。
  • b (break): 不带参数表示查看断点位置,带lineno(行号)表示把断点添加到该行,带filename:lineno表示把断点添加到filename中的第lineno行,带functionname(函数名)表示把断点添加到该函数执行的第一行。tbreak的使用同b,只不过其执行一次后自动删除,故被称为临时断点。
  • c (continue): 持续执行下去直到遇到断点。unt lineno: 持续执行直到运行到指定行。
  • a: 在函数中时打印函数的参数和参数的值。
  • whatis expression: 打印表达式的类型,常用来打印变量值。
  • interact: 启动一个python的交互式解释器,使用当前代码的全局命名空间(使用ctrl+d返回pdb)。
  • w: 打印堆栈信息,最新的帧在最底部。箭头表示当前帧。
  • q: 退出pdb。

Genhiy...大约 15 分钟PythonCodeBook