2018年11月

  • 专门的Nonetype类型
  • ""(Null)是str类型

个人理解,面向对象的时候,没有对象的情况,就需要用None,表示没有对象,对象为空值.

""(Null)就很明了,只是一个数据值为空,这是没有数据一个结果.

https://foofish.net/python-closure.html

https://blog.csdn.net/liang19890820/article/details/73927601

del用法

del只是删除变量的标签

if __name__=='__main__':
    a=1
    b=a
    c=a
    del a
#    print(a)
'''
Traceback (most recent call last):
  File "<pyshell#12>", line 6, in <module>
    print(a)
NameError: name 'a' is not defined
'''
    print(b)
    #1

闭包

闭包满足的条件:

  • 存在一嵌套函数
  • 嵌套函数必须引用封闭(外界)函数中定义的值(也即自由变量)
  • 封闭函数必须返回嵌套函数

例子:

def outer(x):
    print("outer is used...")
    def inner():
        print("inner is used..")
        return x
    print("inner prepares return")
    return inner

重新写了一个例子,发现嵌套函数无法对传入外界函数的值123进行修改.

在内嵌函数中对x加1报错

Traceback (most recent call last):
  File "<pyshell#92>", line 1, in <module>
    f()
  File "<pyshell#88>", line 3, in inner
    x+=1
UnboundLocalError: local variable 'x' referenced before assignment

这个错误的意思是:内部的x在没有赋值(assignment)的情况下,被引用(referenced)了.

猜测:传入内嵌函数的数据是不可变对象,如果想保留原变量名赋值,
x+=1 or x=x+1,需要取出值,运算,再创建了一空间存放,即
新建了一个变量x指向新值,新变量和外部变量冲突?

ref提到

在一个作用域里面给一个变量赋值的时候,Python自动认为这个变量是这个作用域的本地变量,并屏蔽作用域外的同名的变量。很多时候可能在一个函数里添加一个赋值的语句会让你从前本来工作的代码得到一个UnboundLocalError。


传入list测试

def myouter():
    x=[1,2,3]
    print("outer的id:",id(x))
    def inner():
        x.pop()
        print("inner的id:",id(x))
        print("inner_outer_pop:",x)
        return x
    print("outer:",x)
    return inner
    '''
    outer的id: 2407175808520
    outer: [1, 2, 3]
    inner的id: 2407175808520
    inner_outer_pop: [1, 2]
    [1, 2]
    '''

继续查看资料

py3加入新关键字nonlocal

def outer():
    count=0
    def inner():
        nonlocal count
        count+=1
        return count
    return inner

即可解决之前的报错问题

闭包的好处

  • 装饰器
  • 取代硬编码中的常量
  • 避免使用全局值,并提供某种形式的数据隐藏。
  • 提供一致的函数签名
  • 实现面向对象

所有函数对象都有一个 __closure__ 属性,如果这个函数是一个闭包函数,那么会返回的是一个由 cell 对象组成的元组。cell 对象具有 cell_contents 属性,存储了闭包中的自由变量。

>>>sqr.__closure__
      
(<cell at 0x0000023076949B28: int object at 0x00007FFF390ED440>,)

>>>sqr.__closure__[0].cell_contents
      
2

string->listint->list
list(str)list(map(int,str(int)))
list->stringlist->int
''.join(list)int(''.join([str() for _ in list]))

Global Intepreter lock(全局解释器锁)

  • Python-解释语言

编译器:类似JAVA,生成中间文件.class文件
解释器:类似Python,不生成中间文件,可以直接运行
1.png

  • Python是解释语言,其操作原理如下:

    • 读一行代码--->解释为字节码--->运行字节码--->读取下一行(终行结束)
  • Python-变量回收
  • Python中一个变量的回收实现,是存在一个引用计数变量(以下简称引用计数),当它变为0的时候,这个变量就会被释放,下图是个引用计数的例子.
import sys
a=[]
b=a
sys.getrefcount(a)
#3

getrefcount(a) 显示a的引用计数变量,现在的值.

  • 在资源竞争状态下,比如多个线程,如果这个引用计数不被保护起来,那么可能就会出现内存泄露,即一个资源无法被释放,或者一个资源还存在,却发生s不正确的释放.
  • GIL只能保证同一时刻同一CPU上只有一个线程执行,但不能保证线程切换的时候能把一行代码翻译成的字节码执行完,这就会出现问题,所以说只是一定程度上的保证线程安全。
  • GIL只存在于Cpython解释器中,也即是在解释器层面限制了多线程的执行.
  • 对于其他语言,有一些没有使用GIL,如Java.

先记录这些,留个坑来补.

reference:

https://www.cnblogs.com/2bjiujiu/p/9150380.html

https://realpython.com/python-gil/