美文网首页
用好TensorFlow得先学好Python,Python关键字

用好TensorFlow得先学好Python,Python关键字

作者: 木木爱吃糖醋鱼 | 来源:发表于2018-07-05 08:37 被阅读0次

    最近要改TensorFlow结构,在网上搜别人的代码的时候,看到了一个完全vectorize的写法的代码。他的代码中所有的内容都是用tf封装起来,以张量的形式表现的,这导致我觉得我之前根本不会用tensorflow,只用个sess.run去训练就完了。

    为了改他的代码为我所用,第一步得先看懂他写的东西。然而我这个半路出家的java背景的家伙发现有很多python的概念我还是不懂。比如关键字“with”到底是干什么用的。然后我再stackoverflow上找了找解释with的的帖子,发现很多例子里有“yield”,这个是什么我又不知道。解释yield的帖子又提到了generator。。。。。心里一阵mmp,这tm又是个啥?? 这一下午,我怀着吃了狗屎一样的绝望心情,把这3个点弄会了,搭起了下一步通往理解vectorize写法的基础。在这里我把这三个关键字做个笔记,希望对别人有所帮助。

    既然我是倒着看会的,那就先记录generator和yield。

    Generator:

    generator在java里没有对应的概念。它的特点是创建一个只能iterate一次的东西,不能被叫第二次。所以它内部不会把数值存入memory,这样做速度快,而且节省空间。比如有一个随机数数组,只需要用一次。那就没必要用数组来储存,用generator就好了。

    建立generator跟建立数组差不多,区别是数组用中括号【】,而generator用小括号(),比如下面的例子:

    myGenerator = (x * 2 for x in range(256))  # Generator expression

    myList = [x * 2 for x in range(256)]  # List comprehension

    如果不知道这种写法,在看python代码的时候就容易出问题。有时候用debug模式一步一步追看也容易看到什么东西本来刚创建出来,怎么莫名其妙的就跳出func没了??

    不明真相的好奇宝宝们,欢迎把下面的代码那走自己用debug模式运行一下,你会发现第二段代码的mygenerator里面显示是个object的reference,而不是[0,1,4]。这说明generator也是个object。mygenerator只能被叫一次,虽然第一次iterate mygenerator之后你会发现这个变量所保持的object还存在,但是第二个for loop不会打印任何东西,也不会报错。因为里面的东西已经空了。

    # 第一段

    mylist = [x * x for x in range(3)]

    for i in mylist:

        print(i)

    # 第二段

    mygenerator = (x*x for x in range(3))

    for i in mygenerator:

        print(i)

    for i in mygenerator:

        print(i)

    除了面的写法,generator还可以伪装成函数的样子。如果一个函数里面有一个或几个“yield”,这个函数就是个generator。比如下面的例子:

    1 def createGenerator():

    2    mylist = range(3)

    3    for i in mylist:

    4        yield i

    5        yield i*i

    6 mygenerator = createGenerator() # create a generator

    7 print(mygenerator) # mygenerator is an object!

    8 for j in mygenerator:

    9    print(i)

    上面的例子里,def createGenerator()每一次会创建一个generator,所以它可以被多次调用。


    Yield:

    借着上面的例子,再解释一下yield。yield和generator是相辅相成的一对儿,就像炸酱面和大蒜一样~  yield其实就是方程的关键字“return”。只不过generator的return叫“yield”。不光写法不一样,yield和return的机理也有点不同。

    要想明白yield,首先要明白一点,就是当创建generator被叫的时候,方程的主体不会运行。如果你在前5行代码放breakpoint的话,在第6行结束时你会发现不会停在前5行。因为他只是返回了一个generator的object给变量。真正会运行函数主体的是第8行,在for-loop iterates generator的时候。这时候程序会一直运行,直到遇到第一个yield。这是方程会做一个标记(我猜啊,再详细的没看过),然后返回yield后面的东西给for-loop里的j用,然后返回方程,从上一次标记的下一行开始继续运行。。。如果上面的代码把“yield” 改成“return”,程序就会报错,因为for-loop 不能 iterate一个数字(3.3版以前的python不允许generator里面出现return的)。如果是yield就不会报错,因为这时候iterate的是generator object,这个object会根据里面的yield会把数值一个个喂给j。

    With:

    这个在stack overflow上查了好久,越看越懵逼。 最后还是在CSDN大神里找到了简单的解释。只要把他的运作流程和作用写出来就好了嘛,干嘛说那么一对不相干的,越看越懵。。。

    简单来说,with就是个方便书写而加入的statement(计算机科学里叫syntactic sugar),它是用来代替try-except-finally的。或者说with可以帮助写代码的人处理try-except-finally的逻辑,因为try-except-finally写不好是容易出逻辑错误的,但是用了with就可以无脑一行解决。所以with其实是一种encapsulation。

    try-except-finally是用于执行可能出现exception的语句的。比如打开了文件最后要保证关闭,那么就要写好长。用with语句就一行,

    with xxx [as X]:

        #执行啥啥啥

    这个xxx是一个expression,expression是什么都行。如果是方程,返回的东西就赋值给as后面的变量。如果是个class,就会叫class里的__enter__函数,把它返回的值赋值给as后面的变量。整体的流程是这样的:

    1,计算xxx,并获取一个上下文管理器。

    2,上下文管理器的__exit__方法被保存起来用于之后的调用。

    3,调用上下文管理器的__enter__方法

    4,如果with表达式包含as X,那么xxx的返回值被赋值给X。

    5,执行啥啥啥中的表达式

    6,调永上下文管理器的__exit__方法。如果啥啥啥的执行过程中发生了一个异常导致程序退出,那么异常中的type、value、和traceback(也就是sys.exc_info()的返回值)将作为参数传递给__exit__方法,然后异常抛出在控制台。否则将传递三个None值。

    那个上下文管理器在这里有解释。

    这么一看是不是很清晰了? 如果你写一个自己的class,希望以后被with调用的话,那么也要加入__enter__和__exit__两个方程。总之with是个新的protocol,是用于那些需要后续处理的process的,它能够保证在执行完毕之后的清理工作可以顺利进行,并且不需要自己写一大堆繁琐的try-except-finally。如果还不明白,或者有陌生感的话,看下面的referece吧。

    弄清了这些东西,现在我可以愉快的看tensorflow了~~~

    generator的syntax:

    https://www.cnblogs.com/hump/p/6287462.html

    https://stackoverflow.com/questions/47789/generator-expressions-vs-list-comprehension

    generator和yield:

    https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do

    with:

    https://blog.csdn.net/yxwb1253587469/article/details/52248565

    https://blog.csdn.net/u014745194/article/details/71424909

    https://blog.csdn.net/zhuhai__yizhi/article/details/78095650

    https://stackoverflow.com/questions/26342769/meaning-of-with-statement-without-as-keyword

    https://stackoverflow.com/questions/3012488/what-is-the-python-with-statement-designed-for

    相关文章

      网友评论

          本文标题:用好TensorFlow得先学好Python,Python关键字

          本文链接:https://www.haomeiwen.com/subject/pfruuftx.html