python模块

python模块

       在Python里一个py文件,就可以理解为模块(module)。如果要让一个py文件能够被导入,模块名字必须遵守命名规则。

       模块就好比工具包,要想使用工具包里的工具(就好比函数),就需要导入这个模块。
 
一、导入模块

       导入模块的几种方式:

  • import 模块名

  • from 模块名 import 功能名

  • from 模块名 import *

  • import 模块名 as 别名

  • from 模块名 import 功能名 as 别名

       1、import 模块名   

       在Python中用关键字import来引入某个模块,比如要引入系统模块math,就可以在文件最开始的地方用import math来引入。

语法:
import 模块1,模块2,...   #导入方式
模块名.函数名()   #使用模块里的函数

  如果多个模块中有相同的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用谁?所以导入函数的时候要加上模块名。

示例:
import math
print(math.sqrt(2))   #正确
print(sqrt(2))     #报错

  2、from...import 

       如果只需要调用模块中的某个或某些指定的函数,只需要引入该函数即可,此时可以用以下方法实现:

语法:
from 模块名 import 函数名1、函数名2...

  不仅可以引入函数,还可以引入一些全局变量、类等。

       注意通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当导入两个模块的时候如果含有相同的函数名,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function(),模块B中也有函数function(),如果导入A中的function()在先,B中的function()在后,那么当调用function()函数的时候,是去执行模块B中的function()函数。

       示例:导入模块fib中的fibonacci函数,使用如下语句:
from fib import fibonacci

  此时不会把整个模块(fib)导入到当前的命名空间中,它只会将fib里的fibonacci单个函数引入。

       3、from...import *

       把一个模块的所有内容全部导入到当前的命名空间也是可行的,只需使用如下声明:

from 模块名 import *

  这提供了一个简单的方法来导入一个模块中所有的项目。然而这种声明不该被过多的使用。

       4、from 模块名 import 功能名 as 别名

       当“as 别名”后,功能名就不能用了,凡是用到功能名的地方,必须用别名。
import time as ti     #导入模块设置别名为ti,ti代替的是模块名time
time.sleep(2)    #报错
ti.sleep(2)   #使用别名才能调用方法

from time import sleep as sp #导入方法时设置别名sp,sp代替的是方法名
sleep sleep(1) #报错
sp(1) #使用别名才能调用方法

  

 二、常见系统模块

       为了方便程序员开发代码,Python提供了很多内置的模块给程序员用来提高编码效率。

       本文浅谈os模块/sys模块/math模块/random模块/datetime模块/time模块/calendar模块/hashlib模块/hmac模块/copy模块/uuid模块/

       1、OS模块

       os全称operation system,即操作系统模块,这个模块可以用来操作系统的功能,可以实现跨平台操作。
import os
os.getcwd()    #获取当前的工作目录,即当前python脚本工作的目录
os.chdir('test')   #改变当前脚本的工作目录,相当于shell下的cd命令
os.rename('abc.txt','cba.txt')    #文件重命名
os.remove('cba.txt')   #删除文件
os.rmdir('demo')      #删除空文件夹
os.removedirs('demo')    #删除空文件夹
os.mkdir('demo')      #创建一个文件夹
os.chdir('c:\')      #切换工作目录
os.listdir('c:\')    #列出指定目录里的所有文件和文件夹
os.name   #nt(windows)  posix(其他)
os.environ     #获取到环境配置
os.environ.get('PATH')    #获取指定的环境配置

os.path.abspath(path)    #获取path规范化的绝对路径
os.path.exists(path)     #如果path存在,则返回True
os.path.isdir(path)      #如果path是一个存在的目录,返回True,否则返回False
os.path.isfile(path)     #如果path是一个指定的文件,返回True,否则返回False
os.path.splitext(path)   #用来将指定路径进行分离,可以获取到文件的后缀名

       2、sys模块

       该模块提供对解释器使用或维护的一些变量的访问,以及与解释器强烈交互的函数。
import sys
sys.path   #模块的查找路径 
sys.args   #传递给Python脚本的命令行参数列表
sys.exit(code)    #让程序以指定的退出码结束

sys.stdin    #标准输入。可以通过它来获取用户的输入
sys.stdout    #标准输出。可以通过修改它来来改变默认输出
sys.stderr   #错误输出。可以通过修改它来改变错误删除

  3、math模块

       math模块保存了数学计算相关的方法,可以很方便的实现数学运算。
import math
print(math.fabs(-100))   #取绝对值
print(math.ceil(3.24))   #向上取整
print(math.factorial(5))   #计算阶乘
print(math.floor(34.123))   #向下取整
print(math.pi)   #π的值,约等于3.1415926
print(math.pow(2,10))   #2的10次方
print(math.sin(math.pi/6))   #正弦值
print(math.cos(math.pi/3))   #余弦值
print(math.tan(math.pi/2))   #正切值

  4、random模块

       random模块主要用于生成随机数或者从一个列表里随机获取数据。
random.random()   #生成[0,1)的随机浮点数
random.uniform(20,30)   #生成[20,30]的随机浮点数
random.randint(10,30)    #生成[20,30]的随机整数
random.randrange(20,40)    #生成[20,30)的随机整数
random.choice('abcde')     #从列表里随机取出一个元素
random.sample('abcdefg',3)   #从列表里随机取出指定个数的元素

  5、datetime模块

       datetime模块主要用来显示日期时间,这里主要涉及date类,用来显示日期;time类,用来显示时间;datetime类,用来显示日期时间;timedelta类用来计算时间。
import datetime
datetime.date(2020,4,28)     #创建一个日期
datetime.time(15,22,19)      #创建一个时间
datetime.datetime.now()      #获取当前的日期时间
datetime.datetime.now()+datetime.timedelta(3)    #计算三天后的日期时间

  6、time模块

       除了使用datetime模块里的time类以外,python还单独提供了一个time模块,用来操作时间。time模块不仅可以用来显示时间,还可以控制程序,让程序暂停(使用sleep函数)。
time.time()     #获取从1970-01-01 00:00:00 UTC到现在时间的秒数
time.strftime("%Y-%m-%d %H:%M:%S")    #按照指定格式输出时间
time.asctime()    #Mon Apr 15 20:02:22   2020
time.ctime()    #Mon Apr 15 20:02:22   2020

print('hello')
print(time.sleep(6))   #让线程暂停6秒
print('world')

  7、calendar模块

       calendar模块用来显示一个日历。
calendar.setfirstweekday(calendar.SUNDAY)   #设置每周起始日期码。周一到周日分别对应 0-6
calendar.firstweekday()   #返回当前每周起始日期的设置。默认情况下,首次载入calendar模块时返回0,即星期一
c=calendar.calendar(2020)   #生成2020年日历,并且以周日为起始日期码
print(c)     #打印2020年日历
calendar.isleap(2020)   #True      闰年返回True  否则返回False
calendar.leapdays(1990,2020)   #获取1990年至2020年一共有多少个闰年
calendar.month(2020,3)    #2020年3月的日历

  8、hashlib模块

       hashlib是一个提供字符加密功能的模块,包含MD5和SHA的加密算法,具体支持md5,sha1,sha224,sha256,等算法。该模块在用户登录认证方面应用广泛,对文本加密也很常见。
import hashlib
str='这是一个测试'       #待加密信息
h1=hashlib.md5('hello'.encode(encoding='utf8'))
print('MD5加密后为:'+h1.hexdigest())   # MD5加密后为:5d41402abc4b2a76b9719d911017c592

h1=hashlib.sha1('12345'.encode())
print(h1.hexdigest())   #8cb2237d0679ca88db6464eac60da96345513964
h2=hashlib.sha224('12345'.encode())
print(h2.hexdigest())    #a7470858e79c282bc2f6adfd831b132672dfd1224c1e78cbf5bcd057
h3=hashlib.sha256('12345'.encode())
print(h3.hexdigest())  #5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5
h4=hashlib.sha384('12345'.encode())
print(h4.hexdigest())  #0fa76955abfa9dafd83facca8343a92aa09497f98101086611b0bfa95dbc0dcc661d62e9568a5a032ba81960f3e55d4a

  9、hmac模块

       HMAC算法也是一种单项加密算法,并且它是基于上面各种哈希算法/散列算法的,只是它可以在运算过程中使用一个密钥来增强安全性。hmac模块实现了HAMC算法,提供了相应的函数和方法,且与hashlib提供的api基本一致。
import hmac
h=hmac.new('h'.encode(),'你好'.encode())   #随机key:h   加密字符串:‘你好’
result=h.hexdigest()
print(result)    #获取加密后的结果

  10、copy模块

       copy模块里有copy和deepcopy两个函数,分别用来对数据进行浅复制和深复制。
  • copy.copy 是将父对象的值复制了一份,但是子对象指向同一内存地址
  • copy.deepcopy 将父子对象的值全部复制一份,和原对象已没有任何关系
import copy
a = [1,2,3,4,['a','b']]  #原始对象
b = a  #赋值,传对象的引用
c = copy.copy(a)
d = copy.deepcopy(a)
a.append(5)
a[4].append('c')
print('a=',a)     #a= [1, 2, 3, 4, ['a', 'b', 'c'], 5]
print('b=',b)     #b= [1, 2, 3, 4, ['a', 'b', 'c'], 5]
print('c=',c)     #c= [1, 2, 3, 4, ['a', 'b', 'c']]
print('d=',d)     #d= [1, 2, 3, 4, ['a', 'b']]

  11、uuid模块

       UUID是128位的全局唯一标识符,通常由32字节的字符串表示。它可以保证时间和空间的唯一性,也称为GUID。通过MAC地址、时间戳、命名空间、随机数、伪随机数来保证生成ID的唯一性。随机生成字符串,可以当成token使用,也可当成用户账户、订单号使用。

方法
作用
uuid.uuid1()
基于MAC地址,时间戳,随机数来生成唯一的uuid,可以保证全球范围内的唯一性。
uuid.uuid2()
算法与uuid1相同,不同的是把时间戳的前4位置换为POSIX的UID。不过需要注意的是python中没有基于DCE的算法,所以python的uuid模块中没有uuid2这个方法。
uuid.uuid3(namespace,name)
通过计算一个命名空间和名字的md5散列值来给出一个uuid,所以可以保证命名空间中的不同名字具有不同的uuid,但是相同的名字就是相同的uuid了。【感谢评论区大佬指出】namespace并不是一个自己手动指定的字符串或其他量,而是在uuid模块中本身给出的一些值。比如uuid.NAMESPACE_DNS,uuid.NAMESPACE_OID,uuid.NAMESPACE_OID这些值。这些值本身也是UUID对象,根据一定的规则计算得出。
uuid.uuid4()
通过伪随机数得到uuid,是有一定概率重复的
uuid.uuid5(namespace,name)
和uuid3基本相同,只不过采用的散列算法是sha1

       一般而言,在对uuid的需求不是很复杂的时候,uuid1方法就已经够用了,使用方法如下:
import uuid
print(uuid.uuid1())   #根据时间戳和机器码生成uuid,可以
print(uuid.uuid4())    #随机生成uuid,可能会有重复

'''
使用命名空间和字符串生成uuid。
注意两点:
1、命名空间不是随意输入的字符串,它也是一个uuid类型的数据
2、相同的命名空间和相同的字符串,生成的uuid是一样的。
'''
print(uuid.uuid3(uuid.NAMESPACE_DNS,'hello'))
print(uuid.uuid5(uuid.NAMESPACE_OID,'hello'))

  

三、自定义模块

       除了使用系统提供的内置模块外,我们还能自己写模块供自己的程序使用。一个py文件就是一个模块,所以,自定义模块很简单,基本上相当于创建一个py文件。但是,需要注意的是,如果一个py文件要作为一个模块被别的代码使用,这个py文件的名字一定要遵守标识符的命名规则。

       1、模块的查找路径

       创建一个模块非常简单,安装标识符的命名规则创建一个py文件就是一个模块。但是问题是,我们需要把创建好的这个py文件放在哪个位置,在代码中使用import语句才能找到这个模块呢?

       python内置sys模块的pyth属性,列出了程序运行时查找模块的目录,只需要把我们穿件好的模块放在任意一个目录里 即可。
import sys

print(sys.path)
# ['E:\cblog_essay', 
# 'E:\cblog_essay', 
# 'D:\anaconda\python38.zip', 
# 'D:\anaconda\DLLs', 
# 'D:\anaconda\lib', 
# 'D:\anaconda', 
# 'D:\anaconda\lib\site-packages', 
# 'D:\anaconda\lib\site-packages\win32', 
# 'D:\anaconda\lib\site-packages\win32\lib', 
# 'D:\anaconda\lib\site-packages\Pythonwin']

  2、__all__的使用

       使用from <模块名> import * 导入一个模块里所有内容时,本质上是去查找这个模块的__all__属性,将__all__属性里的声明的所有内容导入。如果这个模块里没有设置__all__属性,此时才会导入这个模块里的所有内容。
 
test1.py:模块里没有__all__属性
a='hello'
def fn():
    print('我是test1模块里的fn函数')

test2.py:模块里有__all__属性

x='你好'
y='good'
def foo():
    print('我是test2模块里的foo函数')
__all__=('x','foo')

导入test1.py和test2.py

from test1 import *
from test2 import *

print(a)
fn()

print(x)
#print(y)    会报错,test2的__all__里没有变量y
foo()

 3、模块里的私有成员

       模块里以一个下划线_开始的变量或函数,是模块里的私有成员,当模块被导入时,以_开头的变量默认不会被导入。但是它不具有强制性,如果一个代码强行使用以_开头的变量,有时也可以。但是强烈不建议这样使用,因为有可能会出问题。
 
test3.py:模块里有以_开头的属性
m='早上好'
_n='下午好'
def _bar():
    print('我是test3里的bar函数')

导入test3.py

from test3 import *

print(m)
#print(_n) 会报错,导入test3时,_n不会被导入
import test3
print(test3._n) #也可以强行使用,但是强烈不建议

  4、__name__使用

    在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息。

test.py

def add(x,y):
    return x+y
    
#以下这段代码只有直接运行这个文件进行测试时才要执行
#如果别的代码导入本模块,这段代码不应该被执行
result=add(2,5)
print('测试的结果是:',result)

demo.py

import test.py    #只要导入了test.py,就会立刻执行test.py代码,打印测试内容

       为了解决这个问题,python在执行一个文件时有个变量__name__。在python中,当直接运行一个py文件时,这个py文件里的__name__值是__main__,据此可以判断一个py文件是被直接执行还是以模块的形式导入。

修改test.py
def add(x,y):
    return x+y
    
if __name__=='__main__':   #只有直接执行这个py文件,__name__的值才是__main__
    #以下代码只有直接运行这个文件才会执行,如果是文件被别的代码导入,下面的代码不会执行
    result=add(12,22)
    print('测试的结果是:',result)

  

注意:在自定义模块时,自定义模块名不要和系统的模块名重名,否则会出现问题!

原文地址:https://www.cnblogs.com/shixiaoxun/p/14478053.html