zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【python 4】python 模块

2023-09-14 09:13:57 时间

一、模块

python 中,模块是代码组织的一种方式,把功能相近的函数放到一个文件中,一个文件(.py)就是一个模块(module),模块名就是文件名去掉后缀 py,这样做的好处是:

  • 提高代码的可复用,可维护性,一个模块编写完毕后,可以很方便的在其他项目中导入
  • 解决了命名冲突的问题,不同模块中相同的命名不会冲突

1、如何自定义模块
2、使用系统的模块

二、自定义模块

import 模块名
s = 模块名.方法

导入模块方式:

  • import 模块名
    • 模块名.变量 模块名.函数 模块名.类
  • from 模块名 import 变量/函数/类
    • 在代码中可以直接使用
  • from 模块名 import *
    • 全部导入,也可以在模块中使用__all__=[]来限制可以访问的内容
  • 所有import 的形式,所有的内容都会加载,包括模块里边执行的方法,但我们不希望这个方法永远都被执行,就会加一个 if __name__ == '__main__'。在自己的模块里边__name__==_ main _ ,如果在其他模块调用自己,则_ name _就是自己模块的名字。

1、import 模块名

# calculate 模块
# * --utf--8
# 变量
number = 100
name = 'calculate'
# 函数
def add(*args):
    if len(args)>1:
        sum = 0
        for i in args:
            sum += i
        return sum
    else:
        print('至少传入两个参数')
def minus(*args):
    if len(args)>1:
        m = 0
        for i in args:
            m -= i
        return m
    else:
        print('至少传入两个参数')
def multiple(*args):
    pass
def divece(*args):
    pass
# 类
class Calculate:
    def __init__(self,num):
        self.num = num
    def test(self):
        print('正在进行计算...')
    @classmethod
    def test1(cls):
        print('----------> calculate 的类方法')
调用的脚本
# 导入模块
import calculate
list1 = [4,7,8]
# 使用模块中的函数 模块名.变量 模块名.函数 模块名.类
result = calculate.add(*list1)
print(result)
# 使用模块变量
print(calculate.number)
# 使用模块中的类
cal = calculate.Calculate(80)
cal.test()
calculate.Calculate.test1()
>>>
19
100
正在进行计算...
----------> calculate 的类方法

2、from 模块名 import 函数/变量/类

from calculate import add
result = add(*list1)
print(result)
>>>
19

3、from 模块名 import *

from calculate import *
result = add(*list1)
print(result)
>>>
19

有时候不希望 * 拿到所有,也可以限制能找到的方法,把希望找到的方法放到__all__ 里边就好啦。

# calculate.py 里边加
__all__ = ['add', 'number']

4、模块里边有自身调用的函数

# calculate.py 里边的函数,并且调用了
def test():
    print('我是测试...')
test()

执行调用的时候:

from calculate import *
result = add(*list1)
print(result)
>>>
我是测试...
19

如果不希望加载调用,则解决方法是:

if __name__ == '__main__':
	test()

运行 calculate.py

if __name__ == '__main__':
    print(__name__)
    test()
>>>
我是测试...
__main__
我是测试...

也就是说:__name__ 的值就是 __main__

运行 part5.py

print(__name__) 方法 外层,用 part5.py 调用后,运行 part5.py

def test():
    print('我是测试...')
test()
print(__name__)
if __name__ == '__main__':
    test()
>>>
我是测试...
calculate
19

也就是说 if __name__ == __main__ 只有在本类里边才成立,才会执行里边的内容。别的模块调我的时候,__name__== 模块名,所以不会执行的。

三、包

在这里插入图片描述
文件夹(Directory):存放非 .py 文件
包(Python Package):存放 .py 文件

# article/models.py
class Article:
    def __init__(self, name, author):
        self.name = name
        self.author = author
    def show(self):
        print('发表文章的名字:{},作者是:{}'.format(self.name,self.author))
class Tag:
    def __init__(self, name):
        self.name = name
# user/models.py
class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password
    def login(self, username, password):
        if username == self.username and password == self.password:
            print('登录成功!')
        else:
            print('登陆失败!')
    def show(self):
        print(self.username, self.password)

包下面的模块中的类的调用:

from user.models import User
u = User('admin', '123456')
u.show()
>>>
admin 123456
from article.models import Article
a = Article('个人冻结','nana')
a.show()
>>>
发表文章的名字:个人冻结,作者是:nana
article
	|--models.py
	|--__init__.py
	|--...
user
	|--models.py
	|--__init__.py
	|--test.py
	|--...
part5.py
calculate.py

1、导入方式:

fromimport 模块
from.模块 import|函数|变量
from.模块 import *
from .模块 import 类(.表示当前目录下的)

注意:所有的 from 都是在项目的基础上导入的,所以从 test.py 里边调用 calculate.py 的时候,直接 from calculate import * 就好啦。

# test.py
from user.models import User
from article.models import Article
u = User('admin','123456')
a = Article('个人总结','nana')
u.publish_article(a)
>>>
admin 发表了文章: 个人总结
from calculate import add
list1 = [1,2,3]
result = add(*list1)
print(result)
>>>
admin 发表了文章: 个人总结
6

2、__init__.py 的作用
__init__.py 文件的作用:当导入包的时候,系统会默认先执行这个文件里边的东西。

  • 有这个文件就相当于包
  • 没有这个文件就相当于文件夹

__init__ 的作用:

  • 当包被导入的时候,把一些初始化的函数,变量,类定义在 init.py 中,只要调用包,这些动作就会被执行。
  • 此文件中的函数、变量等的访问,只需要通过 包名.函数名就可以访问。

from 模块 import *:默认所有的函数都可以调用,不定义 __all__ 的时候,所有的东西都可以访问,如果定义了 __all__ ,则在 __all__ 里边的可以访问。

from 包 import *:默认所有的模块都不能访问,如果需要方法,则需要在 __init__.py 里边加上__all__=['model','...']

包:user

# user/__init__.py
print('--------> user的__init__')

在这里插入图片描述

# 调用 user 这个包
import user
>>>
--------> user的__init__

也就是说,只要调用了这个包,就会执行 __init__.py里边的内容。当导入包的时候,系统会默认先执行这个文件里边的东西。

3、循环导入

循环导入是一种错误的方式,可能出现模块间相互引用的情况,应该避免这种情况。

# A 模块里边调用了 B 的函数,B里边也调用了 A 的函数
A:
	def test():
		f()
B:
	def f():
		test()

解决方法:
1、重新架构
2、把 import 放到代码中间,不要放在开头

# xunhuandaoru1.py
from xunhuandaoru2 import func
def task1():
    print('------> task1')
def task2():
    print('------> task2')
    func()
if __name__ == "__main__":
    task1()
    task2()
# xunhuandaoru2.py
def func():
    print('----> xunhuandaoru task1')
    from xunhuandaoru import task1
    task1()
    print('----> xunhuandaoru2 func')

四、sys模块

当你导入一个模块,python 解析器对模块位置的搜索顺序是:
1、当前目录
2、如果不在当前目录,python则搜索在 shell 变量 PYTHONPATH 下的每个目录
3、如果都找不到,python 会查看默认路径,unix 下的默认路径为 /usr/local/lib/python/。模块搜索路径保存在 system 模块的 sys.path 变量中,变量包含当前目录。

import sys
print(sys.path)
print(sys.version)
print(sys.argv)  # 得到运行程序时的参数,也就是执行程序时,给python解释器传一些参数,argv 本身是一个列表,默认放的是程序本身,这里我从外部传了一个 100,所以列表里边出现了 100.

>>>
['C:\\Users\\man.wang\\python\\千峰 python', 'C:\\Users\\man.wang\\python\\千峰 python', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\python37.zip', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\DLLs', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\lib', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\win32', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Users\\man.wang\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\Pythonwin']
3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)]
['C:/Users/man.wang/python/千峰 python/sys_module.py', '100']

pycharm 传参:
在这里插入图片描述
在这里插入图片描述

五、time 模块

    %Y  Year with century as a decimal number.
    %m  Month as a decimal number [01,12].
    %d  Day of the month as a decimal number [01,31].
    %H  Hour (24-hour clock) as a decimal number [00,23].
    %M  Minute as a decimal number [00,59].
    %S  Second as a decimal number [00,61].
    %z  Time zone offset from UTC.
    %a  Locale's abbreviated weekday name.
    %A  Locale's full weekday name.
    %b  Locale's abbreviated month name.
    %B  Locale's full month name.
    %c  Locale's appropriate date and time representation.
    %I  Hour (12-hour clock) as a decimal number [01,12].
    %p  Locale's equivalent of either AM or PM.

1、时间戳:time.time()

import time
t = time.time()
t1 = time.time()
print(t)
print(t1)
>>>
1589196425.641966 (s)
1589196425.641966 (s)

2、延迟执行time.sleep()

import time
t = time.time()
print(t)
time.sleep(3)
t1 = time.time()
print(t1)
>>>
1589196500.979713
1589196503.9804628

3、将时间戳转化为字符串 time.ctime(t)

s = time.ctime(t)
print(s)
>>>
Mon May 11 19:32:30 2020

4、将时间戳转化为元组 time.localtime(t),可以利用 . 来调用里边的值

s = time.localtime(t)
print(s)
print(s.tm_yday)
>>>
time.struct_time(tm_year=2020, tm_mon=5, tm_mday=11, tm_hour=19, tm_min=34, tm_sec=3, tm_wday=0, tm_yday=132, tm_isdst=0)
132
19

5、将时间戳的形式转化为字符串

t2 = time.strftime('%Y-%m-%d %H:%M:%S')
print(t2)
>>>
2020-05-11 19:47:08

6、把元组的时间转化为时间戳time.mktime(t)

s = time.localtime(t)
t1 = time.mktime(s)
print(t1)
>>>
# 只是取到秒级别
1589196947.0

7、将字符串转化为元组的方式

t3 = time.strptime('2020/05/11','%Y/%m/%d')
print(t3)
>>>
time.struct_time(tm_year=2020, tm_mon=5, tm_mday=11, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=132, tm_isdst=-1)

time 模块重点:

  • time()
  • sleep()
  • strftime('格式')

六、datetime 模块

datetime 模块:
	time 时间
	date 日期
	datetime 日期时间
	timedelta 时间差
import datetime
print(datetime.date.today())
>>>
2020-05-11

时间插值的获取:timedelta(hours = N),N 表示N个小时前

t0 = datetime.timedelta(hours=2)
print(t0)
t1 = datetime.datetime.now() # 得到当前的日期和时间
print(t1)
# 时间差
t = t1-t0
print(t)
t = t1+t0
print(t
>>>
2:00:00
2020-05-11 20:00:04.238013
2020-05-11 18:00:04.238013
2020-05-11 22:00:04.238013

七、random 模块

# 1、产生0~1间的随机数
import random
ran = random.random()
print(ran)
>>>
0.5145308460653738
# 2、random.randrange(start, end, steps) 在范围内产生一个随机数,不包含start和end
ran = random.randrange(1,10,2)
print(ran)
>>>
5
# 3、在范围内产生一个随机数,包含 start 和 end
ran = random.randint(1, 10)
print(ran)
>>>
1
# 3、随机选择人名,随机选择列表的内容
list1 = ['nini','nana','lili']
ran = random.choice(list1)
print(ran)
>>>
nana
4、打乱列表的顺序 shuffle
pai = ['红桃A','方片K','梅花J']
result = random.shuffle(pai)
print(result)
print(pai)
>>>
None
['方片K', '红桃A', '梅花J']

练习:

def func():
    code = ''
    for i in range(4):
        ran1 = str(random.randint(0,9))
        ran2 = chr(random.randint(65, 90))
        ran3 = chr(random.randint(97,122))
        r = random.choice([ran1, ran2, ran3])
        code += r
    return code
code = func()
print(code)
>>>
Mru5
3nqN

chr 和 ord:

# 1、chr() unicode ——> str
print(chr(65))
print(chr(19979))
>>>
A
下

# 2、ord() str ——> unicode
print(ord('A'))
print(ord('上'))
>>>
65
print(ord('上'))

八、hashlib

base64是可以加密解密的,md5是单向的不能解密。

import hashlib
msg = '中午一起吃饭!'
md5 = hashlib.md5(msg.encode('utf-8'))
print(md5.hexdigest())  
>>>
c13f458695dfb84daa6dadfb8098987a

九、第三方模块

pip install xxx