11,模块和自定义模块

1,自定义模块的相对导入与测试

这个是我的文件的目录结构,加红线是要使用的文件,搞清楚目录结构否则会很绕。

在zz.py中添加一个变量和一个函数

'''
项目中的子模块
'''

age_zz = 'zz'
def func_zz():
    print('in func_zz')

在yy.py中的操作

'''
此模块作为对外引用的入口
'''

# 相对导入同项目下的模块
# from ..z import zz   # 引用当前目录(y目录)的父目录下的z目录
# 这个方法向外界说明了yy调用了zz模块


# 此时就可以用' from ..z.zz import * '方法导入zz.py文件中的成员
from ..z.zz import *
func_zz()        # 这样就可以调用zz.py中的方法


# 定义yy.py中自己的成员
age_yy = 'yy'

def func_yy():
    print('in finc_yy')

# 这时yy里面不仅仅有自己定义的成员,还有zz模块里的成员



# 另一种方法导入模块
# 通过当前文件路径找到z的路径

import os
import sys
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'z'))
from zz import *
print(age_zz)
func_zz()



a.py

'''
自定义模块
'''

a = 1
print(a)

for x in range(3):
    print(x)


# 函数定义
def f():
    print('hello world')

f()



# __name__:脚本方式运行时,输出固定的字符串:__main__
# 以导入的方式运行时,就是本模块的名字,,现在运行test模块得到的结果是a
print(__name__)



# 当在开发这个模块时,使用if判断,此时test模块不会执行a模块里的可执行语句,也仅仅返回一个a
# if __name__ == '__main__':
#     print(a)
#     for x in range(3):
#         print(x)
#     f()

tbjx.py

# print('from the tbjx.py')

name = '太白金星'

def read1():
    print('tbjx模块:', name)

def read2():
    print('tbjx模块')
    read1()

def change():
    global name
    name = 'barry'
    print(name)



# print(__name__)     # 根据文件的角色(脚本,模块)不同返回的值不同
# 当tbjx.py做脚本时:__name__ = __main__   返回True
# 当tbjx.py做模块被别人引用时:__name__ = tbjx


# __name__根据文件根据文件的角色(脚本,模块)不同返回的值不同
# 1,模块需要调试时加上if __name__ == '__main__':
# change()        # 测试代码  在脚本里用会输出barry,在模块里还是会输出barry.
# if __name__ == '__main__':      # 此时change()只会在脚本里执行,不会再模块里执行
#     change()
# 2,作为项目的启动文件时需要。

上面a.py和tbjx.py是等会要使用的测试内容

在同一个目录下的文件模块导入

自定义模块被其他模块导入时,其中的可执行语句会立刻执行
import a
import time
print(a.a)        # 得到a.py中变量a的值  后面还会输出0 1 2 遍历会直接执行
a.f()             # 输出hello world
# python中提供了一种可以判断自定义模块是属于开发阶段还是试用阶段
# __name__:脚本方式运行时,输出固定的字符串:__main__
# 以导入的方式运行时,就是本模块的名字,,现在运行test模块得到的结果是a

当a.py中只有print(__name__)时

运行a.py输出的结果是__main__

运行导入了a.py的文件时对应的print(__name__)会输出文件名a不带后缀。

不同目录下的文件模块导入

如果a不和执行文件在同一个文件夹下的操作
这里用模块2的tbjx模块

方法1:

# 进行路径搜索
# 先查看当前路径
import sys
print(sys.path)
# 然后添加tbjx.py模块到sys.path中
import sys
sys.path.append(r'D:\python 代码文件\python全栈学习\11-自定义模块(2)')     # 这个就是tbjx.py的父级目录的绝对地址
原理就是直接将调用的模块的路径给系统去找这个模块

方法2:

# 使用相对路径找到tbjx.py
import sys
import os
print(__file__)     # D:\python 代码文件\python全栈学习\10-自定义模块(1)\test 模块.py      # 找到当前文件的路径
print(os.path.dirname(__file__))    # D:\python 代码文件\python全栈学习\10-自定义模块(1)     # 找到当前文件路径的父目录
#
# 则上面的可以写成
path = os.path.dirname(os.path.dirname(__file__))       # 获得本文件的爷目录  获取几个上级目录要看两个文件的想路径差了几级
print(path)     # D:\python 代码文件\python全栈学习
path2 = os.path.join(path, '11-自定义模块(2)')
os.path.join(path, '11-自定义模块(2)') # 获得了同一个根目录后再添加分支的目录名,
# 这个目录名下存在tbjx这个文件,一级一级要把所有的文件夹join进去一直写到tbjx.py的父目录
sys.path.append(path2)      # 将要调用的模块的路径添加给系统,进行搜索
import tbjx
tbjx.change()

导入模块的多种方法

# 将自定义模块添加到sys.path路径中
import os
import sys
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), '11-自定义模块(2)'))
# 上一行等价于下面三行
'''
path = os.path.dirname(os.path.dirname(__file__))
path2 = os.path.join(path, '11-自定义模块(2)')
sys.path.append(path2)
'''

导入模块的第一种方法

import tbjx
tbjx.change()

导入模块的第二种方法

from tbjx import change
change()

def change():
    print('****')

change()        # ****
这时将会容易发生模块与脚本中的变量重名,系统分不清楚该调用谁,会就近调用change(),因此不建议用此方法调用模块

解决方法:

起别名

# 1,给成员起别名
from tbjx import change  as  a
a()     # barry
# 2,给模块起别名
import tbjx  as b
b.change()      # barry

2,random--随机数模块

此模块提供了随机数获取的相关方法
'''
此模块提供了随机数获取的相关方法

'''

import random


# 1 random.random()    # 获取[0.0,1.0)范围内一个16位小数的的浮点数,
a = random.random()
print(a)


# 2 random.randint(a, b)      # 获取[a, b]范围内的一个整数
b = random.randint(1, 5)
print(b)


# 3 random.uniform(a, b)      # 获取[a, b)范围内一个16为小数的的浮点数
c = random.uniform(1, 5)
print(c)


# 4 random.shuffle(x)     # 把参数指定的数据中的元素打乱,参数必须是一个**可变的数据类型**。
x = [1, 2, 3, 4, 5, 6]
random.shuffle(x)
print(x)        # [2, 3, 4, 1, 6, 5]
# 不可变数据类型如何打乱
tup = (6, 5, 4, 3, 2, 1)
lis = random.sample(tup, len(tup))
print(tuple(lis))


# 5 random.sample(x, k)       # # 从x中随机抽取k个数据,组成一个列表返回
x = [1, 2, 3, 4, 5, 6, 4, 7, 8, 9, 0]
lis = random.sample(x, 5)
print(lis)

3,time--时间模块

'''
time模块
'''

import time

# 1,
# 获取时间戳
# 时间戳:从时间元年(1970年1月1日00:0:00)到现在经过的秒数
second = time.time()
print(second)

# 2,
# 获取格式化时间对象
print(time.gmtime())        # GMT:时间
# time.struct_time(tm_year=2023, tm_mon=8, tm_mday=6, tm_hour=1, tm_min=4, tm_sec=59,tm_wday=6, tm_yday=218, tm_isdst=0)
print(time.gmtime(1))       # 获取时间元年过一秒后,对应的时间对象
# time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)

# 时间对象--->时间戳 -没啥用
print(time.mktime(time.localtime()))
print(time.time())


# 3,
# 当地时间:
print(time.localtime())
# time.struct_time(tm_year=2023, tm_mon=8, tm_mday=6, tm_hour=9, tm_min=6, tm_sec=38, tm_wday=6, tm_yday=218, tm_isdst=0)


# 4,
# 格式化时间对象和字符串之间的转换
# 1,将格式化时间对象转化成字符串
s = time.strftime('%Y %m %d %H:%M:%S')
print(s)  # 2023 08 06 09:21:43 显示当时的时间

# 2,将字符串转化成格式化时间对象
time_obj = time.strptime('2023 08 07','%Y %m %d')
print(time_obj)
# time.struct_time(tm_year=2023, tm_mon=8, tm_mday=7, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=219, tm_isdst=-1)


# 5,
# 暂停当前时间,睡眠(一般用于模拟程序运行时间)
time.sleep(5)      # 睡眠5秒
for i in range(5):
    print(time.strftime('%Y-%m-%d  %H:%M:%S'))
    time.sleep(1)

4,datetime--日期模块

datetime:日期时间模块

封装类一些和时间,日期相关的类。

date
time


datetime
timedelta
    这俩并不是用于表示的而是用于数学运算
'''
datetime:日期时间模块

封装类一些和时间,日期相关的类。

date
time


datetime
timedelta
    这俩并不是用于表示的而是用于数学运算
'''

import datetime
# from datetime import *
# date类:年/月/日 可以获取date的各个属性
#
d = datetime.date(2010, 10, 10)
print(d)  # 2010-10-10
# # 可以获取date类的各个属性
print(d.year)  # 2010
print(d.month)  # 10
print(d.day)  # 10


# # time类:时:分:秒
#
t = datetime.time(10, 56, 24)
print(t)        # 10:56:24
# # 获取time类的各个属性
print(t.hour)       # 10
print(t.minute)     # 56
print(t.second)     # 24


# datetime:主要用于数学运算  **** 只能是datetime类和timedelta和date类之间进行运算
dt = datetime.datetime(2023, 8, 15, 15, 42, 3)
print(dt)
# timedelta:表示时间的变化量
td = datetime.timedelta(days=1)     # 表示时间变化一天
print(td)
# 参与数学运算
# 创建时间对象
# date,datetime,timedelta
d = datetime.date(2023, 12, 15)
res = d + td
print(res)      # 2023-12-16
#
#
# 时间变化量的计算会产生进位
t = datetime.datetime(2023, 8, 12, 12, 15, 26)
td = datetime.timedelta(minutes=15, seconds=50)  # 计算上面的时间15分钟50之后的时间
res = t + td
print(res)  # 2023-08-12 12:31:16

练习:

计算某年二月份有多少天

'''
思路:
    1,闰年二月份29天,不闰年二月份28天
    2,使用datetime模块
    3,首先创建指定年份的3月1日,然后让他往前走一天
    4,类型和操作数保持一致
# '''
year = int(input('请输入年份:'))
s = datetime.date(year, 3, 1)
td = datetime.timedelta(days=1)
res = s - td
if res.day == 29:
    print(f'{res.year}年二月份有29天')
else:
    print(f'{res.year}年二月份有28天')

5,os--操作系统模块

'''
os:操作系统相关的操作被封装到这个模块中
'''

import os

# 和文件操作相关的
# 1,删除文件
os.remove('')       # ''中写文件路径
# 2,重命名
os.rename('', '')       # 前面参数写旧名,后面参数写新名
# 3,删除目录,目录必须是空的
os.removedirs('')       # ''中是目录名
# 使用shutil模块可以删除有内容的目录
import shutil
shutil.rmtree('')       # ''中是需要删除的目录名


# 和路径相关的操作,被封装到另一个子模块中:os.path
# 1,当前文件的父目录
ret = os.path.dirname(__file__)       # 当前文件的父目录
print(ret)      # D:\python 代码文件\python全栈学习\10-自定义模块(1)
# 2,分割当前文件的绝对路径的最后一级 输出为元组
ret = os.path.split(__file__)       # 分割当前文件的绝对路径的最后一级 输出为元组
print(ret)      # ('D:\\python 代码文件\\python全栈学习\\10-自定义模块(1)', '06-os--操作系统模块.py')
# 3,将路径b追加到路径a后面
ret = os.path.join('a', 'b')     # 将路径b追加到路径a后面
print(ret)      # a\b
# 4,判断括号里的文件是否存在,括号内的可以是文件路径
ret = os.path.exists(r'D:\\python代码文件\\python全栈学习\\01-python基础\\10-自定义模块(1)\\03-random--随机数模块.py')        # 判断括号里的文件是否存在,括号内的可以是文件路径
print(ret)      # True 输出为布尔值
# 5,判断是不是目录,找不到也是False
ret = os.path.isdir(r'D:\\python代码文件\\python全栈学习\\01-python基础\\10-自定义模块(1)\\模块的相对导入')       # 判断是不是目录,找不到也是False
print(ret)      # True 输出为布尔值
# 6,判断是不是文件,找不到也是False
ret = os.path.isfile(r'D:\\python代码文件\\python全栈学习\\01-python基础\\10-自定义模块(1)\\模块的相对导入')      # 判断是不是文件,找不到也是False
print(ret)      # False 输出为布尔值
# 7,将相对路径转换成绝对路径
ret = os.path.abspath('模块的相对导入')        # 将相对路径转换成绝对路径
print(ret)      # D:\python代码文件\python全栈学习\01-python基础\10-自定义模块(1)\模块的相对导入
ret = os.path.abspath(r'\a\b\c')
print(ret)  # D:\a\b\c
ret = os.path.abspath(r'a\b\c')
print(ret)      # D:\python代码文件\python全栈学习\01-python基础\10-自定义模块(1)\a\b\c
'''
如果是以\开头的路径默认是在当前盘符下
如果不是以\开头的路径默认是在当前目录下
'''
# 8,判断是不是绝对路径
ret = os.path.isabs(r'模块的相对导入')       # 判断是不是绝对路径
print(ret)        # False 输出为布尔值
# 9,如果a是绝对路径 则这个方法是取路径结尾的名
ret = os.path.basename('a')     # 如果a是绝对路径 则这个方法是取路径结尾的名
print(os.path.basename(r'D:\python 代码文件\python全栈学习\10-自定义模块(1)\模块的相对导入'))       # 模块的相对导入


# # walk 获得该路径下的所有文件和文件夹
import os
g = os.walk(r'D:\python 代码文件\python全栈学习')
for i in g:
    path, dir_list, name_list = i
    print(path, dir_list, name_list)
    print(i)

6,sys--与python解释器相关模块

'''
和python解释器相关的操作

'''
import sys

# 解释器寻找模块的路径
print(sys.path)

# 添加解释器寻找模块的路径
sys.path.append('')

7,collections模块

collections模块
    namedtuple():命名元组
    defaultdict():默认值字典
    Count():计数器
import collections

# # namedtuple():命名元组
Rectangle = collections.namedtuple('Rectangle_class', ['length', 'width'])
ret = Rectangle(10, 5)
# # 通过属性访问元组的元素
print(ret.length)
print(ret.width)
# # 通过索引的方式访问元组的元素
print(ret[0])     # 10
print(ret[1])     # 5


# # defaultdict():默认值字典
# # 创建一个字典的方式:
d = {'name': 'Andy', 'age': 10}
d = dict([('name', 'Andy'), ('age', 10)])
d = dict(name='Andy', age='18')
print(d)
d = collections.defaultdict(int, name='Andy', age=18)
print(d['name'])      # Andy
print(d['age'])       # 18 找不到返回0
print(d['addr'])        # 找不到返回0 并且还会被添加
print(d)        # defaultdict(<class 'int'>, {'name': 'Andy', 'age': 18, 'addr': 0})
# # 自定义一个函数充当第一个参数: 将函数的返回值做新的键值对的值
# # 要求,不能有参数
def func():
    return 'hello'

d = collections.defaultdict(func, name='Andy', age=10)
print(d['addr'])
print(d)        # defaultdict(<function func at 0x0000013B05BD6798>, {'name': 'Andy', 'age': 10, 'addr': 'hello'})


# Count():计数器
b = collections.Counter('XDFHSDFGDRSGDSRGDFFFGDFGDFDFD')
print(dict(b))        # Counter({'D': 9, 'F': 8, 'G': 5, 'S': 3, 'R': 2, 'X': 1, 'H': 1})
print(b.most_common(3))     # [('D', 9), ('F', 8), ('G', 5)] 取出出现次数前三的统计情况

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

  • 15
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值