模块导入与内置模块

模块:
    本质上就是以.py结尾的文件。 其目的就是为了文件里的代码实现一些功能

包:
   就是包含有__init__.py文件的目录。  包和文件夹仅仅只差了这个文件

 

import 模块               导入的本质就是搜索路径把python文件解释一遍                                    所以导入模块就一定要找到路径

                                 直接用import调用的是标准库模块,python自己内置的 。  import 会先在环境变量中找这个模块,然后执行一遍引用的模块。所以一般引用模

                                  块 都是功能函数,没有逻辑运算和处理

rom 模块 import 函数   这个跟上面原理不同,它完全是把函数copy到了要导入的模块中(存在函数同名的情况,还是会执行执行本
                                   身函数,非要执行导入的同名函数,可使用  from 模块 import 函数 as  别名    。执行别名函数就行)
                                  直接在本身模块上用该函数就行。


   from 包  import 包      导入包和导入模块是完全不同的概念和原理    
                                     导入包是执行包里面的__init__.py文件    导入模块是把模块里面的数据赋值一个变量,然后调用变量里的东西

 

普通导入模块或者里面方法

import    module                           在环境变量中找module文件路径,并执行一遍搜索到的模块                                    

from module import  m1               相当于把m1函数函数直接copy到当前模块中

from  module import *                   把module模块中的函数全部引入到当前模块     不建议用(易与当前模块重名)

from  module import m1 as bie     把引入的函数换个变量名这样避开当前模块重名函数

 

模块和包平级,包里面模块导入包外和模块

import sys,os
x = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #从当前的文件向上两级目录的路径
sys.path.append(x) #把这个路径加入环境变量,就能找到需要导入函数路径了

import day10 #能找到模块了
day10.shoping()

 

外面包导入里面模块

from haha import number                                                                                #用from把模块相当于抄写在当前模块中                                                           

number.test()

 

包里面模块导入另一个包模块

其实和上面是一样的,添加环境变量,导入模块即可

import sys,os
x = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(x)

from ha2 import goog2 #从ha2包中找到goog2模块
goog2.bb3()

 

导入包

import bao                                                                                                           其实就是解释包里面的__init__文件  没什么意义,我们一般都是要导入包里面模块                                                                                                                

import sys,os                                                                                                      #增加环境变量,才能找到博爱的路径                                                            

x = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

sys.path.append(x)

import ha2                                                                                                      #导入包 其实就是执行__init__文件,如果要执行包里面的模块,只能在__init__中导入模块,且只能用(from导入)

 

 

 

注意,我们也可以使用.表示当前目录,再用.表示父目录       os.chdir(..)     其实就是切换了目录,退到了父目录,再进行文件的创建和删除的时候都是当前父目录开始算起的,    但是执行当前文件的程序不受影响    因此可

                                          以不用不用加环境变量,直接切换到父目录,再来胯包调用包,而当前模块不受影响      (可以用,但是要考虑以后是否会要在当前位子创建文件,

                                          因为只能创建到父目录里面去,当前创建不了,也删除不了 )

也可以用   目录.下级目录.模块   来表示层级调用

 

 

 

init文件

 

print('这是init文件')
from . import goog2 #其实这里注意了 ,当我们导入一个模块的时候,导入的模块中还有导入模块操作时(1——》2,2——》3)在2中用import找3模块的话,1无法找到3模块(3路径没在环境变量中),可以在2中用from
#来导入模块,相当于copy3模块到2模块中,1模块当然能执行3模块的函数了

导入包,并且调用里面的模块

 

 

import sys,os
x = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(x)

import ha2

ha2.goog2.bb3()

 

 

 

 

 

 

导入不同级别目录模块


跨项目(包)来导入模块时:
           由于当前处在不同的包内,当导入模块时,就会按它的环境变量sys.path(是一个列表)里面的路径去搜索导入模块文件。由于找不到
肯定会报错,所以我们要增加父包或者父父包(向上退2级或者3级)路径到环境变量中来使它能被找到导入。
           __file__当前文件的路径    dir =  os.path.abspath(__file__)当前文件的绝对路径      os.path.dirname(__file__) 当前文件的父目录


 
导入和优化  
         如果模块中的数据被重复调用很多次  那么每次调用的时候就会先找文件再去执行,重复去找的过程其实浪费很多资源。我们可以
         用 from 模块 import 这种导入方式 ,把函数直接copy来直接用,而不用反复去找文件调用

关于在导入包时注意的事项
        如果需要跨包调用模块,则是在调用成功包后,执行的是包下面的__init__文件,需要在此文件中引用需要导入的模块,但是由于__init__的特殊,
此文件导入必须以from . import 模块   的形式来导入
       原来需要导入的模块调用时应该是    调用的包名字.模块名.函数

 

第三方模块             自己安装

 

自定义模块            自己编辑

 

 

除了添加环境变量(要导入模块路径),如果遇见多层级向内可用.表示

from  web1.web2  import haha                                           #调用web包里面web2包里面的haha模块

from  web1.web2.haha import bb                                      #                                                               中 bb的函数

 

 

关于   __name__ == '__main__'

__name__ 为系统的变量    当在自己执行文件中时 ,其值就是 __main__

当在被调用(被导入)的模块中执行的时候 ,其值就是导入模块的路径

 

__name__ == '__mian__' 的作用

一个模块中有这个作为判断函数执行开始的标志 ,这样执行当前文件的话,条件下的程序才会运行      如果是在导入模块中有这个语句,因为导入模块会解释一遍模块,有逻辑程序就会被执行。加入__name__=='main'避免了这些程序导入时被执行

(执行文件中加入这个表示文件中这个条件以下的程序调用的时候无权去使用)

 

time  模块

   1  时间戳:  time.time()        显示的是1970年到目前为止的为多少秒

   2 格式化的时间字符串           自己定义时间格式的一串字符

参数表示       timezone   时区显示                       
               time.time()  时间戳
               time.sleep(2) 延迟2秒  
               time.gmtime() 不输入时间戳的话,把当前时间戳转换成的结构化的世界标准时间UTC          
               time.localtime()                                            当地时间,显示结构化的时间                   

               这2个是把时间戳变   
               time.mktime()  输入结构化时间,输出时间戳
               time.strftime()  把结构化的时间变成成字符串时间        time.strftime("%Y-%m-%d %H:%M:%S",x)  x 为结构化时间    如time.localtime
               time.strptime()  刚好相反                                       ("2018-11-2 11:06:01","%Y-%m-%d %H:%M:%S) 输出结构化的时间    %H:%M:%S 可以用%X代替
                

结构化时间
time.localtime()
time.gmtime()
#将结构化时间转换成时间戳 时间戳是全数字,可以进行加减,得出中间时间
time.mktime(time.localtime())


计算时间(时间戳) 结构化是展示的


结构化时间——————字符串时间 相互转换
print(time.strftime('%Y-%m-%X',time.localtime())) #将结构化时间变成字符串时间, %X表示小时分秒

 

如果不想定义字符串时间,又想快捷显示出来

print(time.asctime())                           #里面不填参数默认填入当前结构化时间,输出固定格式字符串时间

print(time.ctime())                              #                                   当前时间戳,输出固定格式字符串时间                                     省去了一些麻烦

 

datetime 模块

datetime.datetime.now()                  #输出固定格格式的字符串时间   相比上面的格式更符合中国人习惯

 

内置模块 random
          random.random() 随机取一个0到1之间的浮点数   
          random.randrange(1,3)  不包含最后一个         random.randint(1,3)  包含最后一个
          random.choice()   传入字符串,列表等在里面随机取一个元素
          random.sample("hello",2) 随机多位元素,组成列表                    前面一个是可循环元素(不能为字典) 后面接去元素个数
          random.uniform()  在random.random()基础上可以指定区间
          random.shuffle()  洗牌,打乱输入的数据顺序,不能对字符串作用。

print(random.random())
print(random.randint(1,3))
print(random.randrange(1,3))
print(random.choice([bb.values()]))
print(random.sample('abcdefg',2))
print(random.uniform(0,1))
a = [1,2,3]
random.shuffle(a) #注意shuffle是函数,更改顺序,不是取值,因此直接打印是打印这个函数的return值
print(a)



os模块
     
     os.getcwd()   获取当前的工作目录              os.chdir('a') 切换当前目录             os.pardir()  获取当前目录的父目录

     os.makedirs('a\b')   递归创建目录             os.removedirs('a') 递归删除空目录      os.mkdir('a')  不能递归建
     
     os.stat(a)       文件状态,只能对包和目录使用 os.listdir(a)  列出目录下的文件        os.environ 系统环境变量
     
     os.removedir(a)   删除一个空文件夹            os.path.dirname(a) 当前文件的目录      os.path.basename() 当前文件的名称
     os.path.exists()  判断路径是否存在            os.path.isabs()  是否是绝对路径        os.path.join(a,b)   路径拼接 (很常用)
     os.path.getatime(a)  文件或者目录的创建时间   os.path.getmtime(a) 修改时间  
     os.sep    路径的分隔符  不同系统路径 分割符不同 windows 是\ Linux是/
     os.linesep    换行符也是不同   r\n       Linux中  \n
     os.pathsep    环境变量的分隔符
    


sys 模块
       sys.exit() 退出python程序       sys.version 获取py的版本信息(不常用)  
       sys.path   环境变量              sys.platform 返回操作系统名称
       
       sys.argv()  这是我们调用模块的时候,可以输入参数也可以不输出,不管参数用没有用,都会以列表存储下来。我们可以根据里面参数不同调用不同的程序,
                    与input对比的话,就是可以模块一开始执行的时候,就写入存储执行完程序,不会像in表示put程序走到一半或者哪里卡住,等输入再执行。
        sys.stdout.write('#')   进度条      
        sys.stdout.flush()    刷新上次输入的值              文件刷新是 文件名.fulsh

 json序列化  (非常重要)            
     json做任何数据交换   不管是不是相同语言
          1 序列化就是把内存上的对象变成字符串存在硬盘上,反序列化就是加载回来。
          2 不同语言数据传输   python中的列表和表现形式  通过json传 到c语言就变成数组类型,和表现形式

import json
a = {"name":"huangjian","age":26,"sex":"men"}
f = open("密码","w",encoding="utf-8")

#f.write(json.dumps(a))                              #json dumps将a 变成json字符串    什么是json字符串:会把里面的''变成"",再套一层"",并且可以被任何语言识别

#print(json.loads(f.read())["name"])                  #json loads将字符型串f.read()变成字典类型

#josn 只能转换简单的字符串,列表,字典,等。但是复杂的函数,类等不能转换。json 是所有语言都通用的
      #主要用途是跟别的语言交互时,可以把py的列表等转换成别的语言的列表。

       注意,json.dumps 和json.loads 不需要绑定在一起     只要字符串符合json字符串的规范(''都是用""表示),直接可以json.loads   两者不不必非要连起来用

                 json不能序列化集合

      我们存的数据只能是两种类型,字符串类型和字节类型                                   这两种类型最终还是会转成机器码及0和1来存储

 

import pickle

 

pickle
      能把复杂的数据转换成二进制的格式保存进硬盘,再可以恢复出来,调用。 且只能在python中用

      关于json.dumps(数据)   和json.dump(数据,存放到的文件夹)     两者区别在于 前者是把数据变成字符串后者是把数据变成 默认
          字符编码存放在文本中     所以有所不同

     json.load后面直接接句柄    json.loads 和json.dumps一样括号里必须是字符串str

程序一
import pickle
def test(name):
    print("hello",name)
f = open("密码","wb")
print(pickle.dumps(test))
f.write(pickle.dumps(test))           #把二进制的格式a写入f 中
程序二
import pickle
def haha(name):
    print("同名函数",name)
f = open("密码","rb")
c = pickle.loads(f.read())
c("huangjian")
                                       这里可以看做是pickle.load把文件的二进制复原找到原来的门牌号为test的函数,由于
                                  不同程序不能相互调用里面的程序,所以如果不命名一个函数为test的函数,则会找不到
                                  函数而报错。根据原理,可以重新定义函数名为TEST的函数。还原来的函数不一样

    注意   其实没什么卵用,pickle能序列化对象,函数   但是序列化后传去不同的程序,他们只是一个变量名,没有实际意义 ,一般用json传的数据类型足够了

 

shelve 模块
         是对pickle的一次封装。跟pickle一样
         d = shelve.open(文件)                    文件名要不存在,它会自动创建新的            创建了一个空字典d
         d("随便什么字符") = 要改变的数据         序列化                                                  相当于添加键和键值
         d.get(上面的字符)                        反序列化                                                         取出键值

 

回顾        

'''
import json

with open('tt','w',encoding = 'utf8') as f:
f.write(json.dumps({'name':'huangjian','age':30})) #序列化(变成符合json的字符串)


with open('tt','r',encoding = 'utf8') as f:
print(type(json.loads(f.read()))) #反序列化


#序列化的目的把数据可以变成所有语言都能识别的,方便数据交换

import pickle
#json一样,多了可以序列化对象。但是没多大用处,传到别的语言位子就仅仅是一个变量名
#pickle序列化的数据是byte类型,注意了,文件存的话只能用byte类型打开
dd = {1,2,3,4}
def ha():
print('this is hanshu')
with open('tt','rb') as f:
# f.write(pickle.dumps(ha)) #序列化函数(函数名而已)
# f.write(pickle.dumps(dd))
print(pickle.loads(f.read()))
#只能用于python程序中
'''
import shelve
#pickle差不多,对它的又一次封装

dd = shelve.open("she__lve") #shelve方法打开一个文件
dd['num1'] = 'dasda' #用字典的方式存数据放到文件中
dd['num2'] = 123
dd['num3'] = {'name':'huang','age':30}

print(dd.get('num1'))      反序列化取值

 

 

 

xml

  因为此序列化的程序出的比json早,因此很多地方程序依旧用在使用xml序列化,虽然json看起来简便,但是无奈它使用的较早,很多地方依然有他的身影

  xml跟上面三种(json,pickle,shelve)方式和思路完全不同,上面的是打开文件直接调用方法来序列化数据

  而xml却不同,而且文本数据是标签格式的,有层级表示数据的所属关系。

  首先     

        1.我们存的数据要创建一个xml的文件(存放数据)   专门的文件形式

         <data>                               #根标签,根节点     没有属性

            <country name ="china">                   #字标签,子节点     有属性 

               <rank update='yes'>2</rank>              再里面的子节点     注意update='yes' 是属性  >2<    2是数据内容 

                   <year>2020</year>                        没有属性,只有数据

                   <neighbor name='japen' deirection='J'/>    

            </country>                          #字标签结束

         </data>                               #结束标签

         怎么创建上面形式的XML文件呢

        import   

 

   

 

        2.我们再使用xml模块中的方法去读这个文件,和写文件

          #查看
           import xml.etree.ElementTree as ET #引用xml模块并且符别名

           tree = ET.parse('xml-less') #parse:解析,这个就是解析(读取)文件,获得一个tree对象(文件句柄)

           root =tree.getroot() #获取到跟节点,就是跟标签

           print(root.tag) #xml中的节点可以使用tag方法,查看节点名

           for i in root: #遍历根节点
           print(i.tag,i.attrib) #节点可以使用attrib来查询节点的属性
           for j in i:
           print(j.text) #节点可以使用text来查看其类容

           for i in root.iter('neighbor'): #只遍历特定节点使用iter方法找节点(特定的标签)
           print(i.tag,i.attrib,i.text) #打印标签名,属性,数据

          #修改
           for i in root.iter('rank'): #找到所有特定标签
           i.set('haha','test') #更改属性
           i.text = "改变的数据" #更改数据,原文件是数字字符串,如果是普通字符串直接赋值

           tree.write('xml-less2.xml') #必须要这一步,把修改好的文件句柄(tree)写入一个文件中,可以是原来的文件(覆盖),也可以是新文件

         #删除

           for i in root.findall('country'):         #findall 寻找root(根节点下)所有的country节点
             rank = int(i.find('rank').text)        #条件,可加可不加
             if rank < 10:
             root.remove(i)                 #删除根节点(root)下面的country节点     注意是i代表每次循环的到country标签,不能直接去用xml里面的标签(coutry或者里面任何标签)
tree.write('xml-less2.xml')                       #这一步不能少,修改的句柄写入一个文件中

 

 

 上面是已经创建好的xml文件,怎么自己创建XML数据

import xml.etree.ElementTree as ET

new_xml = ET.Element("namelist") #new_xml 是根节点 后面方法符名字
haha =ET.SubElement(new_xml,"name",attrib={'a':"1"}) #在父节点(new_xml)下创建haha节点,节点名字是name,数据是{"a":1}

et = ET.ElementTree(new_xml) #把根节点生成句柄(树形结构)
et.write("test.xml",encoding="utf-8",xml_declaration=True) #把树形结构句柄写入新文件

 

 

 

 

 

 


 

 

posted @ 2020-07-02 21:27  xiaojianfir  阅读(377)  评论(0)    收藏  举报