Loading...

Python系列教程235——相对导入
在Python3.0版本后,它只搜索当前的包,如果当前包中没有名为spam的模块,导入就失败了。如果没有相对导入这么一个技术,那么我们将永远无法导入标准库里的string模块,因为上面的代码首先会找到当前包mypkg中的string。有了相对导入这么一个规定,上面的语句就不会搜索mypkg包,那么就会找到标准库里的string。例如你要导入其它包中的模块,那就不是相对导入,而是绝对导入。上面代码的意思是,从当前包中找到一个名为spam的模块,然后导入里面名为name的变量。这就是为什么要使用相对导入!

Python系列教程234——为什么要使用包导入技术?
如果没有套套,你可能就会因为一个不小心而想起那个经典的广告“不是我不小心,只是真情难以抗拒,某某某医院,无痛人流,留住你的产权”。声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!不应该像上面那样在目录内把文件安装成单纯的文件列表,而是应该将它们进行打包,也就是多加个__init__.py文件

Python系列教程233——包导入时使用import还是from
此时,有老粉丝可能会骂我“瞎JB扯蛋,之前在《Python系列教程227——使用import还是from》的文章中还说推荐使用import,现在怎么又说推荐使用from了呢”。例如,在前面文章的例子中,如果我们使用import语句,在每次要得到z时,就得从dir1开始重新输入完整路径,并且每次都要重新执行整个路径。

Python系列教程232——包导入实例
此外,就像模块文件一样,任何已导入的目录也可以传递给reload,来强制该目录重新被执行。下列给出了三个包含简单代码的文件,它们分别位于目录dir1和dir2中——这些文件的路径名会在注释中给出(老铁!这里,dir1要么是我们工作目录的子目录(工作目录就是程序代码所在的目录),要么就是位于模块搜索路径中的一个目录的子目录。

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中步进运行要快得多。

欢迎留下您的脚印