python中的package和modules

2018-10-08  本文已影响0人  hy雅各布

## 如何认识python中的包和模块

//**//作为一个python小菜鸟,刚接触python并没有多久,也只是将将掌握python的基本用法,在一个大佬的胁迫下才会想着发表一些觉得有用的东西,也都属于个人见解,其中有可能还会有很多认识上的错误,希望各路大佬若是很不幸看到的话,帮助一下纠正错误,要是大佬们有什么好的建议能够提出,在下感激不尽,若是有幸刚好帮您得到一些新体会的话,这篇文章也就实现了它的价值,那我们就从这开始吧:**

**1.如何理解包和模块的概念**

      首先,在日常的开发之中,我们经常会遇到对代码的重用,维护以及扩展等问题,当我们在修改代码的时候,无疑代码的耦合是一个大问题,所谓耦合,就是代码块之间的相互关系,本身python最小的运作单元就是一个代码块,也可以解释为一条完整语句,作为解释型语言,当然要将懒(其实也可以解释为方便,都一样)发挥到极致,功能写出来之后像我肯定是不会再想着下次开始再重头写,好比也许我当时处于一个非常极端的状态,比如刚跟女朋友分手之类的,心情极度悲愤的情况下定义出的方法和变量估计日后的我想看看是什么都有一定难度,那么这时候,如果再有可能当时在纯用面对过程的思想随手写的一个功能,后边的代码重用无疑是个大问题。

      那么,如果说不管什么时候我都想再次使用我自己的代码,而且有一种敢为天下先的精神,献出自己的代码给别人使用,不过这时候问题又来了,我自己有可能都忘了自己在和前任女朋友分开时候是什么心情下定义的变量是什么意思,别人大概率也不咋会知道,加上要是耦合度稍微有那么点高,一个复制粘贴也许都变了样子,加上python每次错误缩进都有可能让你有种吃了那啥的冲动,我觉得除了前端的人会很开心直接粘贴复制省时间,我还没见过python粘贴复制省时间的。

      我们再回过头来讲下耦合的问题,在你勇敢地站了出来,将自己的身为程序员的才能发挥到了极致,所有的东西写在了一个python文件中,五六千行代码,可以让人眼花缭乱,然而可怕的是,一旦某一点出错,又像是看到几吨那啥一样恶心,注意,你在后面五六千行代码中还不知道写了啥相关联的东西,满堂红的光彩我要是在一边笑估计会被你打死,耦合意思就是相互联系,动了一个功能代码错的越多,耦合度越高,越说明你逻辑严密,环环相扣,也有可能是粘贴复制太多,牵一发而动全身。这时候我们就可以很开心的提出一个叫做解耦和的概念,这个先声明,解耦合是一种降低耦合度的举动并不是直接让它们一点联系没有,没有直接功能的代码只是一个架子,好比网页的交互,也许你只是做了一个样式让别人欣赏下你做网页的水平,但是,花瓶并不是人人都喜欢的。

      那么,我们该如何摆脱自身逻辑的困扰呢,如果我只是单纯想做一个功能,然后各个我以后的程序里想要使用这个功能可以随时拿过来用,这个时候我们就可以来了解下python中的模块(modules)了。

      既然代码如果写在一个文件中,那么会有很大的量让我来思考和修改,那么我把它细分,相似的功能放在一个文件,比如类型,方法,变量等等,使用一个 “import” 的关键字来引入,是不是就可以很方便就看了,然后不管怎么用,我只要把它带上,到时候修改的时候根据我自己的需求随意修改,这样似乎也是一个很好的选择,很开心如果你接受了这样的思想并且已经知道了import的方式 ,那么这个modules的使用思想我觉得是没什么问题了。

      那么既然模块指的是一个python文件,那么放这个东西的文件夹是什么呢,不会是package(包)吧,如果你是这么想,很好,你已经得到了一半的精髓,我们在使用modules的时候,除非在同一文件夹下,是不能直接引入的,首先pycharm它也找不到,其次就是如果你把几个模块写成了一样的文件名,恭喜你,你自己也许都不知道引入的是哪一个,再者说,你也不能像我上面说的用一次改一次,那个是比较特殊需求的时候,你把它复制出来改一下,大部分时候,功能需求应该是普遍性相似的东西,所以为了再方便一点 ,我们就有了package(包)这个好东西,简单来说,你的modules好比是一个个好用的工具,非特殊时候不用拿出来重新锻造,而你的包就是一个工具箱,你可以把你的工具放在里面,做好区分之后,不管我需要用他们干什么只需要先找到这个包然后就可以拿出我的工具然后快乐自己,不管是维护还是扩展要干什么直接在那个python文件里修改就好了反正也不会碍着其他功能什么事情就算在里面新加多少个module,好比在包里再放上几块砖,只要电脑受的了,反正我自己也不累,这个就是最完美的了。

      不过,还是那一个问题,你说这个文件夹我用来放的是需要我自己单独运行的东西还有一些杂物只是拿出来看看你的包能不能用随便练练手,而且跟我要用的东西有一些相似,名字上有些问题,当然区分方法我们一会会再提出来,那么标准的包和你的文件夹到底有什么区别,它里面还有一个__init__.py的文件,里面装的是__all__=[“。。。”,“。。。”,。。。。],不过这个里面只是你在使用这个包的时候直接可以使用的模块,大多时候吧,这个文件是对包的最好分辨工具,其他文件夹没有这个但是有你的python文件虽然说也可以调用,但是书包和旅行包始终你会知道有什么不一样的,你要是把书包当作一个旅行包用我也没办法,也就看上去不太好看而已,在代码上确实有点不太标准。

  **2.包和模块的使用**

      既然包和模块已经理解的差不多了,那么我们现在可以来学习下它们的用法,那么我们就从以下的流程来看看它们是如何使用的:

`在这里插入代码片`#### 1 包的定义

      因为刚刚已经讲过包本质就是个文件夹,那么我可以设置一个demo01文件夹,在其中设置一个文件夹modules,那么这个文件夹中再设置一个__ init__.py,此时则这个modules就是一个程序包,然后在这个文件夹里我可以放上我的各种python功能文件也就是定义各种模块比如基本的deletes.py,mkdirs.py,...`,里面简单写点代码

import os

def dels(path):

    a=os.path.exists(path)

    if a:

        if os.path.isdir(path):

            b=os.listdir(path)

            if len(b)!=0:

                for i in b :

                    k=os.path.join(path,i)

                    isfile=os.path.isfile(k)

                    if isfile:

                        os.remove(k)

                    else:

                        dels(k)

                os.rmdir(path)

            else:

                os.rmdir(path)

        else:

            os.remove(path)

import os

def mkdirs():

  if not os.path.exists("hy"):

      os.mkdir("hy")

      for i in range(100):

          a=str(i)

          j=os.path.join("hy",a)

          with open(j,"wb") as f_w:

              f_w.write(j.encode())`

这样我的一个小工具包就完成了。。。

2.2 包和模块的复用

            python中包和模块主要是为了自己之前实现的功能的重用,最主要的目的是为了有效的整理代码来实现服用性能

          封装好的包和模块的代码被引入使用,仿佛借用一般,不用那么麻烦的重写等等

  2.2.1  import 和from .. import

        1.import 包/模块

          #引入方式

          import 模块

          #使用模块中的数据

          模块.变量

          模块.函数

          模块.类型

          remark:import 方式可以引入包,模块

          import引入的包和模块会自动从当前文件夹,系统环境变量pythonpath中,以及sys.path 路径中查询是否存在

          如果不存在,就会出现错误:no module named “xxxx”

2.from 包/模块 import 具体对象

  基本语法如下

  from . import xxx #从当前模块路径下引入xxx模块

  from .. import xxx #从当前模块的父级路径下引入xxx模块

  from PKG import module #从PKG包中引入一个模块module

  from PKG.module import vars,func,clazz #从指定模块中直接引入

  remark:from xx import 语法方式,主要是针对出现了包结构的python代码而特定的代码引入方式,首先要非常明确代码的组织结构才能正确私用from import 语法进行代码的引入和复用

  remark!:通过上述代码,可以看到from import 语法区分为两种操作

  1.使用了./..的相对路径的引入操作方式

  2.直接使用包/模块名称的绝对引入操作方式

  包的引入可以通过相对路径直接操作,包既可以是python的包,也可以是一个普通包含python代码的文件夹

  需要注意的是,一旦使用相对路径,就要明确所谓相对路径是依赖它们所属的父级文件夹,相当于在一个屋檐下,兄弟姐妹一样,执行代码的时候需要在命令行中告诉python解释器在路径中 python -m hy01.main

  如果直接在文件夹中执行命令 python main.py 就会出现 importerror:cannot import name “(所引入的module)”

  切记:引入路径相对于当前文件,执行路径相对于引入的最外层文件夹,这样才能正确使用相对引入操作执行我们的模块代码。

  绝对引入的操作方式比较简单,从最外层的包的源头直接开始操纵

  如:from pygame import K_A ,K_S,K_D,K_W

  惯用方式为第三方的模块操作,在独立项目开发较少

  运行操作,和以上的都类似。。。

3  解释包和模块

  模块:

  python中的模块,指代的就是一个python文件

  1,在一个python模块中可以包含的数据有:变量,函数,类型等,是一个完整的独立代码块

  2,独立的一个代码块中的变量:全局变量,局部变量,能被其他模块引入使用的只有当前模块中的全局变量,其他模块对于当前模块中的全局变量的操作和普通变量一致

  3,模块一旦被其他模块引入,就会自动执行模块张的所有代码

  4,模块中的测试代码可以包含在if __name__=="__main__":语句块中,这样就不在引入的时候执行测试代码

  标准模块定义方式如下:

  # coding:utf—8

  #引入系统标准模块

  #引入第三方模块

  #引入自定义开发模块

  #声明定义变量

  #声明定义函数

  #声明定义类型

  #当前模块测试代码

  if  __name__=="__main__":

  #测试代码位置,其他模块引入不会执行这里的代码

  包:

  python解释器在执行处理代码时,会默认将包含python文件的文件夹处理为默认包,默认包只具备文件路径关联的

  功能,无其它功能

  python中的标准包如上,就是在文件夹中声明文件__init__.py,这文件夹就是一个python模块报

定义一个python的数据模型包如下:

demo01/

user/

__init__.py #包声明模块

modules.py #数据类型定义模块

manager.py #数据模型管理模块

menus.py # 界面处理模块

main.py #程序主模块 

需要注意的是 import 包 相当于 导入 import 包.__init__.py 但是不能这么写而已

from 包 import * 是将  在__init__.py中的__all__包含的模块一次性引入 __all__=[.......]相当于

from 包 import ., ., .,.....

  python中的Main方法

  由于python是没有main方法的不像c++之类的

  因此我觉得这个相当于是一个入口 告诉它要不要执行当前python文件的测试代码

  大部分人都喜欢这么写 ,好巧  我也喜欢  所以没办法

  不写这个的后果一瞬间会引入不光你需要的东西,而且会有文件中的测试代码,所以,一般还是加上为好

上一篇下一篇

猜你喜欢

热点阅读