Loading...

python系列教程231——__init__.py
如果选择使用包导入,就必须多遵循一条约束:包导入语句的路径中的每个目录内都必须有__init__.py这个文件,否则导入包会失败。它会只加载该目录的__init__.py文件中赋值语句定义的变量名,包括该文件中程序代码明确导入的任何子模块。例如,导入后,表达式dir1.dir2会返回一个模块对象,而此对象的命名空间包含了dir2的__init__.py文件内所赋值的所有变量名。作为一个高级功能,你可以在__init__.py文件内使用__all__列表来定义目录以from*语句形式导入时,需要导出什么。

python系列教程230——包导入
这个目录就称为包,因此,这类导入就称为包导入。这些语句中的“点号”路径是对应于机器上目录层次的路径,通过这个语句可以导入文件mod.py。也就是说,上面的语句是表明了机器上有个目录dir1,而dir1里有子目录dir2,而dir2内包含有一个名为mod.py的模块文件。此外,这个导入意味着,dir1位在某个容器目录dir0中,这个目录可以在Python模块搜索路径中找到。容器目录dir0需要添加在模块搜索路径中(除非这是顶层文件的主目录,就是放启动文件的那个目录,也就是程序的当前目录)。

python系列教程229——reload重载
例如,必须在启动时通过网络连接服务器的系统,就是动态重载的一个非常重要的应用场景。当然,并非所有系统都需要这种动态的实现,但对那些需要的系统而言,模块重载就提供了一种易于使用的动态定制工具。声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!在下面这个例子中,我们要修改并重载一个模块文件,但是不会中止交互模式的Python会话。我们得调用reload,才能够获取新的版本。

python系列教程228——模块是什么鬼?
例如,假设模块文件M.py的顶层有一个像X=1这样的赋值语句,而变量名X会变成M的属性,我们可在模块外以M.X的方式对它进行引用。在导入时,文件顶层(不在def或class之内)赋值变量的语句(例如,=和def),会建立模块对象的属性,赋值的变量名会存储在模块的命名空间内。系统中,文件在第一次导入时无论在什么地方,Python都会建立空的模块对象,并逐一执行该文件内的语句,依照文件从头到尾的顺序。在一个代码文件的顶层(也就是不在函数或类的主体内)每一个赋值了的变量名都会变成该模块的属性。

python系列教程227——使用import还是from
就像在夜场里,你跟你女朋友去玩,碰巧有另外一个女的跟你女朋友穿了同样的衣服,你以为他是你女朋友,你上去就摸了一把,结果却不是你女朋友,摸错人了。但是无论如何,我觉得在一个大型的多人协作的系统中,尽量使用inport语句,这样会避免很多潜在问题的发生,也有利于系统代码后期的维护。另外一个潜在的威胁就是,当使用reload的时候。

python系列教程226——如何改变其它文件中的变量
使用import是导入了整个文件,也就是把整个文件当成了一个可变对象,所以改变这个可变对象内的变量就会影响到原始文件。就像函数的参数,对已取出的变量名重新赋值,对于其复制之处的模块并没有影响”,那么我们如果想要改变其它文件中的变量的值要怎么操作呢?PS:看不懂本篇文章的同学请先看前面的文章,循序渐进每天学一点就不会觉得难了!

python系列教程225——import和from居然是赋值语句
就像def一样,import和from是可执行的语句,而不是编译期间的声明,而且它们可以嵌套在if测试中,出现在函数def之中等,直到执行程序时,Python执行到这些语句,才会进行解析。赋值语句方面的知识都适用于模块的读取。就像函数的参数,对已取出的变量名重新赋值,对于其复制之处的模块并没有影响,但是修改一个已取出的可变对象,则会影响导入的模块内的对象。此处,x并不是一个共享的可变对象,但y是的。导入者中的变量名y和被导入者都引用了相同的列表对象,所以在其中一个地方的修改,也会影响另一个地方的这个对象。

python系列教程224——导入只发生一次
在默认的情况下,Python只对每个文件的每个进程做一次操作。第二次和其后的导入并不会重新执行此模块的代码,只是从Python内部模块表中取出已创建的模块对象。PS:看不懂本篇文章的同学请先看前面的文章,循序渐进每天学一点就不会觉得难了!

python系列教程223——模块的创建与使用
创建一个Python模块非常非常简单,只需要使用文本编辑器,把一些Python代码输入至文本文件中,然后以“.py”为后缀名进行保存,就会被自动认为是Python模块。上面两个例子有着相同的效果,但是from语句出现时,导入的变量名会复制到作用域内,在脚本中使用该变量名就可少输入一些:我们可直接使用变量名,而无须在嵌套模块名称之后。当我们使用*时,会取得模块顶层所有赋了值的变量名的拷贝。因为from会把变量名复制到另一个作用域,所以它就可以让我们直接在脚本中使用复制后的变量名,而不需要通过模块名称。

python系列教程222——模块导入
此外,如果Python在搜索路径上只发现了字节码文件,而没有源代码,就会直接加载字节码(这意味着你可以把一个程序只作为字节码文件发布,而避免发送源代码)。在这之后,导入相同模块时,会跳过这三个步骤,而只提取内存中已加载的模块对象。因此,通常不会看见程序顶层文件的.pyc字节码文件,除非这个文件也被其他文件导入:只有被导入的文件才会在机器上留下.pyc。因为最后的导入步骤实际上是执行文件的程序代码,如果模块文件中任何顶层代码确实做了什么实际的工作,你就会在导入时看见其结果。2.编译成位码(需要时)。

python系列教程221——模块
这份手册在Python安装后就可以看到(通过Windows上的IDLE或“PythonStart”按钮),或者也可以使用http://www.python.org的在线版本。文件b.py和c.py是模块,a会导入b和c。a.py中的第二行语句调用了模块b中所定义的函数spam,使用了对象属性语法。有下面几种导入方式。

python系列教程220——哪种迭代最快
我们已经学习了多种迭代工具方法,那么哪一种工具最快呢?

python系列教程219——生成器是单迭代器对象
对于生成器函数来说,也是如此,如下的基于语句的def等价形式只支持一个生成器并且在一次迭代之后用尽。这与某些内置类型的行为不同,它们支持多个迭代器并且在一个迭代器中反映它们的原处修改。此外,一旦任何迭代器运行到完成,所有的迭代器都将用尽。

python系列教程218——生成器表达式
注意,如果生成器表达式是在其他的括号之内,在这种情况下,生成器自身的括号就不是必须的了。从语法上来讲,生成器表达式就像一般的列表解析一样,但是它们是括在圆括号中而不是方括号中的。虽然结果一样,但是从执行过程上来讲,生成器表达式很不相同:不是在内存中构建结果,而是返回一个生成器对象,这个对象支持迭代协议。

python系列教程217——生成器函数
yield语句挂起该函数并向调用者发送回一个值,当再次调用这个生成器函数时,它里面的yield语句会接着上次的状态并且再次产生一个值返回给调用者。得到的是一个生成器对象,它支持迭代器协议,也就是说,生成器对象有一个__next__方法,它可以开始这个函数,或者从它上次yield值后的地方恢复,并且在得到一系列的值的最后一个时,产生StopIteration异常。上面的解释还是比较难理解的,大家看如下代码再来慢慢理解,下面代码定义了一个生成器函数,这个函数将会用来不断地生成一系列的数字的平方。

python系列教程216——何时用列表解析
虽然列表解析比较复杂度,但是它却有可观的性能优势:map调用比等效的for循环要快两倍,而列表解析往往比map调用要稍快一些。速度上的差距是来自于底层实现上的,map和列表解析是在解释器中以C语言的速度来运行的,比Python的for循环代码在PVM中步进运行要快得多。

python系列教程215——列表解析与矩阵
虽然这种结构通过行来存储矩阵,但是我们能够简单地通过对行进行迭代,然后从所需要的列中提取出元素,或者就像下面一样通过在行内的位置进行迭代。下面的表达式使用range来生成列表的偏移量,之后使用相同的行和列来进行索引,取出了M[0][0],之后是M[1][1](这里我们假设矩阵有相同数目的行和列)。

python系列教程214——列表解析与for和if
如果你对一个复杂的列表解析有什么困惑的话,你可以将列表解析的for和if分句在其中进行嵌套(将后来的分句缩进到右边),从而得到等效的语句。使用了if分支的列表解析能够当成一种与内置的filter类似的工具,它们会在分支不是真的情况下跳过一些序列的元素。这个表达式排列了从0~4的偶数与从0~4的奇数的组合。实际上,你可以在一个列表解析中编写任意数量的嵌套的for循环,并且每一个都有可选的关联的if分支。通用的列表解析的结构如下所示。当for分句嵌套在列表解析中时,它们工作起来就像等效的嵌套的for循环语句。

python系列教程213——列表解析与map
简而言之,列表解析会把任意一个表达式而不是一个函数应用于一个迭代对象中的元素。列表解析在一个序列的值上应用一个任意表达式,将其结果收集到一个新的列表中并返回。它的简单形式是在方括号中编写一个表达式,在后边跟随着的看起来就像一个for循环的头部一样的语句。现在,假设我们希望收集整个字符串中的所有字符的ASCII编码。

python系列教程212——函数式编程
reduce在Python2.6中只是一个简单的内置函数,但是在Python3.0中则位于functools模块中,要更复杂一些。内置的operator模块提供了一些函数,它们使用起来是很方便的(要了解关于这一模块的更多内容,请参阅Python的库手册)。下面是一个对第一个调用的for循环的等效实现。

欢迎留下您的脚印