Python 小知识

关于局部变量和全局变量

在函数内部或代码块内是可以访问全局变量的,但是是以只读形式访问的,若不加 global 关键字 那么是不能对其进行修改的,若对全局变量进行赋值,默认是会创建一个新的同名局部变量的

而且 在一个代码块内部,如果有新声明的新同名变量,那么就算在其前面也是不能访问到外部的 全局变量的,此时若进行访问,会报错

var = 1

def func():
    print(var) # ok 1
var = 1

def func():
    print(var) # not ok referenced before assignment
    var = 4
var = 1

def func():
    var = 4
    print(var) # ok 4
var = 1

def func():
    global var
    print(var)  # ok 1
    var = 4
    print(var) # ok 4

print(var) # ok 4

Python 中的无返回值方法

例如 list 的 append 操作就是无返回值的,换句话说就是不能进行形如

list = []
list.append(1).append(2)

这样的连续操作

注意函数返回的数据类型

  • 注意是 list 还是 生成器
  • 注意是 list/tuple 还是 单个变量

Python 很注重惰性计算,所以很多函数,方法返回的是 生成器 或者 map 类型,有些时候需要 转换 为 list tuple 等再进行使用

例如 plt.plot(...) 就返回一个 plot 对象的 list, 原因大概是可以这样写 plt.plot(x, y, x, z)

单元素 list tuple 的注意事项

很多函数可能需要返回多个值,所以就会返回 tuple 作为数据类型,但很多时候其返回的 tuple 中又只有一个元素,此时就加逗号咯

line, = ax.plot(Data[0, 0], Data[0, 1],color = 'red',lw = 1.5, label = 'Pos')

类似这样

有时候我们也需要返回一个 tuple 但只有一个元素,所以加逗号咯

def func():
    something()
    return res,

python 中的代码块

if 语句不会产生代码块,也就是不会生成新的变量空间,这点和其他语言不太一样

切片是目标对象的一个拷贝

Python 中,”==” 和 “is”的区别

前者是相等性比较,比较的是两个对象中的值是否相等,后者是一致性比较,比较的是两个对象的内存空间地址是否相同。

面向对象:类中的 __slots__ 方法

定义了类可以使用的方法总和。仅对当前类起作用,其子类不受影响,除非子类中也定义了 __slots__ 方法,那么子类的属性就是自身的 slots 属性加上其父类的 slots 里的属性

关于 python 里的函数调用和定义的顺序

一般情况下,是定义必须在调用之前,但是如果是一个函数内部调用另一个函数,则被调用的函数的定义可以在这个调用函数的后面。另外 类内的函数定义和调用似乎没什么先后顺序

关于 __new__()

实际上 new 就相当于是 C++ 里的构造函数,但是不包含赋值和初始化的部分 一般情况下,不需要手动写 new

关于切片和拷贝的速度

想用 matplotlib 画一个动态图,但是数据是实现读取好的。所以只能不断改变画图数据的大小来实现 plot 的动态过程。 想到两种方法,一个是新建一个 array,然后每一次迭代都 append 一个数据进去,然后 plot 这个 array,另一种方法 是每次对原始数据进行切片,后画图。

后来采用的是切片的方法,发现速度竟然比 append 要快很多,总觉得每一步一次的 append 应该不会比对那么多数据进行浅复制的切片慢啊。

因为数据是存储在 numpy 的 ndarray 中和 Python 内置的 list 可能有些不一样。list 在切片的时候实际上是进行浅拷贝的,而 ndarray 在切片时是返回一个 view(numpy 名词),共享核心数据,但其他的属性例如 shape 等都是不影响的。可能 ndarray 的核心数据都是 flatten 之后存储的吧。

总之,append 很慢,如果知道数组长度就预先分配好空间,如果不知道也尽量少做 append 或者 resize 的操作,用空间换时间是更优解吧。

Python 里的函数可以嵌套定义

虽然这在装饰器里很常见,但如果不是装饰器的话看起来就有点奇怪了

def main():
    def func():
        print('shit')
    func()

>>> main()
shit