|NO.Z.00021|——————————|BigDataEnd|——|Hadoop&Python.v21|——|Arithmetic.v21|语法:进阶&模块和包管理.V3|

一、模块和包管理
### --- 模块和包管理

~~~     Python中具有丰富的标准库和第三方库,学习并掌握模块、包的概念尤为重要,
~~~     决定了我们是否能够利用这些丰富的资源,以及如何妥善组织好我们自己的代码。

一、模块的导入
~~~     # 首先,我们来导入一个内置模块
import math

~~~     # math是Python标准库中的一个模块,用来进行数学运算,我们在上面使用import 关键字将它导入了,现在我们就可以使用它的功能啦。
~~~     # 求一个数的平方根
math.sqrt(4)
~~~     # 现在我们可以使用math模块里的所有函数了,可以使用dir来看一下都有哪些函数
dir(math)

~~~     # 我们也可以使用from ... import ... 这种语句来具体导入某一个子模块或函数
from math import sqrt
sqrt(4)
~~~     # 这种方式更精确的导入某个函数,使用起来更方便, 但要注意重名的问题。如果说我们的代码本来就有一个叫sqrt的函数,那我们可以使用as 关键字来给模块起一个别名
from math import sqrt as squarte
def sqrt(num):
pass
squarte(4) # 2

~~~     # 或者是这样:
import math as math2
math = 0
math2.sqrt(4) # 2
~~~     # 有时候需要一次性导入多个模块,可以这样写
import sys, os
from math import sqrt, pow

~~~     # 注意,在实际调用模块之前,必须先导入,否则将会产生报错。
~~~     # 将会产生NameError
math.sqrt(4)
import math
~~~     # 如果导入一个不存在的模块,也会产生报错
~~~     # 将会产生ModuleNotFoundError: No module named 'maht'

import maht
二、自定义模块
~~~     # 除了使用标准库的模块,我们也可以自己定义模块,实际上,这也是我们在项目中组织代码的基本方式。以上一个综合案例“电商购物车”为例,实际的文件结构应该是这样的:

└── project
├── cart.py  # Cart类
├── goods.py # Goods类
└── main.py  # 入口文件
~~~     # shopcart目录里面,有三个文件,不同的类写在不同的文件内,cart.py和goods.py文件和原来保持一致即可。我们来看看main.py

from cart import Cart
from goods import Goods
g1 = Goods('iPhone 11', 6000, 0.9)
g2 = Goods('U盘32G', 100, 0.8)
g3 = Goods('华为P40', 5000)
cart = Cart()
cart.add(g1)
cart.add(g2, 3)
cart.show()
~~~     # main.py作为项目的入口文件,我们实际运行的时候就是从它启动

python main.py
~~~     # 那Python解释器是怎么找到cart和goods模块的呢?因为它们和main.py在同一个目录下,所以可以自动的发现它们。那如果有很多这样的模块,我们想把它们放到同一个目录下,以便统一管理,该怎么做呢? 比如,需要将cart.py 和 goods.py放到shopcart包内,调整目录结构如下:

├── project
│ ├── main.py
│ └── shopcart
│ ├── __init__.py
│ ├── cart.py
│ └── goods.py
~~~     # 如果发现目录内有名为__pycache__ 的文件夹,那是Python在导入时自动生成的缓存文件,可以忽略。
~~~     # 在mian.py同级目录下,多了一个shopcart目录,注意,shopcart目录里除了cart.py和goods.py目录,还多了一个__init__.py ,这是一个空文件,它的文件名看起来很奇怪,这是Python规定的命名规范,只要目录有一个名为__init__.ppy 的文件,则将这个目录视为包(package),现在修改main.py,作一下调整:

from shopcart.cart import Cart
from shopcart.goods import Goods
~~~     # 同时将下面的部分也做一下调整

if __name__ == '__main__':
g1 = Goods('iPhone 11', 6000, 0.9)
g2 = Goods('U盘32G', 100, 0.8)
g3 = Goods('华为P40', 5000)
cart = Cart()
cart.add(g1)
cart.add(g2, 3)
cart.show()

~~~     # __name__ 表示当前文件所在模块的名称,模块可以通过检查自己的 __name__ 来得知是否运行在main 作用域中,这使得模块可以在作为脚本运行时条件性地执行一些代码,而在被 import 时不会执行。
三、常用内置模块
### --- datetime - 日期时间类型

~~~     # 除了上面使用过的math模块以外,Python还有大概100多个内置模块,下面我们来介绍一下常用的几个模块。
~~~     # datetime模块中包含了几个常用的日期时间类,其中最常用的是datetime和timedelta。
~~~     # 注意,我们在下面使用的datetime是指datetime类而不是datetime模块。
from datetime import datetime, timedelta
~~~     # 返回当前时间的datetime对象
now = datetime.now()
type(now)
~~~     # 查看当前时间的年、月、日
print(now.year, now.month, now.day)
~~~     # 查看当前时间的时间戳,精确到微秒
now.timestamp()
~~~     # 计算机中时间的起始点都是1970年1月1日00:00:00,时间戳就是从1970年1月1日00:00:00到现在总秒数。所以如果时间戳A比时间戳B的值小,说明A在B之前。
~~~     # datetime也提供将日期时间对象和字符串相互转换的操作,这在处理数据时会经常使用。
~~~     # 返回指定格式的日期字符串, 下面的返回 "2020-08-10 20:29:41"
datetime.now().strftime('%Y-%m-%d %H:%M:%S')

~~~     # 将指定格式的字符串转换为日期时间对象
datetime.strptime('2020-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
%Y这种形式是日期时间的格式代码,下面是一些常用的代码含义:
代码 含义 示例
%Y 十进制数表示的带世纪的年份。 2019,2020
%m 补零后,以十进制数显示的月份。 01, 02, ..., 12
%d 补零后,以十进制数显示的月份中的一天。 01, 02, ..., 31
%H 以补零后的十进制数表示的小时(24 小时制)。 00, 01, ..., 23
%M 补零后,以十进制数显示的分钟。 00, 01, ..., 59
%S 补零后,以十进制数显示的秒。 00, 01, ..., 59
~~~     # 还有很多格式,可以查看Python官方文档:https://docs.python.org/zh-cn/3/library/datetime.html#strftime-strptime-behavior
~~~     # 只要得到了datetime对象,我们就可以把它转换成各种格式。同样,只要有一个相对标准化的格式,我们就可以将它转换为datetime对象。
~~~     # 得到datetime对象后,可以对它进行修改,显示去年的今天现在这个时候的时间:

now = datetime.now()
last_year = now.replace(year=2019)
print(last_year.strftime('%Y-%m-%d %H:%M:%S'))
~~~     # 如果我们想知道两个datetime对象之间相差多长时间,可以将这两个对象相减
delta = now - last_year
type(delta)

~~~     # 得到的对象就是一个timedelta对象,我们可以根据timedelta对象知道这两个时间相差多少天多少分多少秒。
delta.days
delta.seconds
~~~     # 现在得到delta就是一个timedelta对象, 它表示366天整的时间,我们也可以将一个datetime对象和一个timedelta对象相加,将会得到一个新的datetime对象:

now + delta
~~~     # 将当前时间加上366天,就是明年的明天。timedelta类提供了非常便捷的方式帮我们处理日期时间,比如我们想要构造:
~~~     # 从当前开始20天后的时间
datetime.now() + timedelta(days=20)

~~~     # 两个半小时之前的时间
datetime.now() - timedelta(hours=2, minutes=30
### --- time - 时间的访问和转换

~~~     # 还有一个经常使用的时间模块time
import time
~~~     # 返回当前时间戳
time.time()
~~~     # 返回当前时间的格式化字符串
time.strftime('%Y-%m-%d %H:%M:%S')
~~~     # 其实time模块的另一个函数我们也经常使用,它可以使我们的程序暂时睡一会儿

print("好累呀,我要小睡3秒钟")
time.sleep(3)
print("好啦,我又元气满满!")

~~~     # sleep函数会将当前的程序暂停若干秒数。
### --- random - 生成随机数

~~~     # 准确的说是生成伪随机数,这是一个数学问题。默认random模块会根据当前的系统时间作为随机数种子,所以可以保证生成的随机数不会重复。
~~~     # 生成一个随机浮点数,范围[0.0, 1.0)
random.random()
~~~     # 生成1到100之间的随机整数,包括1和100
random.randint(1, 100)
~~~     # 从序列中随机抽出一个元素
random.choice(['a', 'b', 'c', 'd', 'e', 'f', 'g'])

~~~     # 从序列中随机抽出k个元素,注意抽出来的元素可能会重复
random.choices(['a', 'b', 'c', 'd', 'e', 'f', 'g'], k=2)
~~~     # 跟choices函数类似,但它是不重复的随机抽样
random.sample(['a', 'b', 'c', 'd', 'e', 'f', 'g'])

~~~     # 将一个序列随机打乱,注意这个序列不能是只读的
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
random.shuffle(lst)
### --- os - 操作系统接口

~~~     # os模块提供了一种使用与操作系统相关的功能的便捷式途径。需要大家了解一些操作系统的知识。
~~~     # 获取当前目录的路径
os.getcwd()
~~~     # 创建指定目录
os.mkdir(path)
~~~     # 与 mkdir() 类似,但会自动创建到达最后一级目录所需要的中间目录。
os.makedirs(path)

~~~     # 返回一个列表,该列表包含了 path 中所有文件与目录的名称。
os.listdir()
~~~     # 另一个很常用的子模块就是os.path,它提供了常用的路径操作。
~~~     # 显示当前目录的绝对路径
os.path.abspath('./')
os.path.abspath("__file__")

~~~     在大部分操作系统中,一般用. 表示当前目录,用.. 表示父级目录
~~~     相对路径:相对于当前目录的路径
~~~     绝对路径:以根目录为开始的路径(windows和Mac、Linux的根目录不同)
~~~     目录分隔符:windows 是 \ , Mac 和 Linux中是 /
~~~     # 如果 path 是 现有的 目录,则返回 True。
os.path.isdir(path)

~~~     # 如果 path 是 现有的 常规文件,则返回 True。
os.path.isfile()
~~~     # 目录分隔符
os.sep

~~~     # 合理地拼接一个或多个路径部分。
os.path.join(path, *paths)
~~~     # 返回路径 path 的目录名称
os.path.dirname("/tmp/test.txt") # '/tmp'

~~~     # 返回路径 path 的基本名称,文件名或是最后一级的目录名
os.path.basename("/tmp/test.txt") # 'test.txt'
os.path.basename("/tmp/test") # 'test'
### --- sys - 系统相关参数及函数

~~~     # 首先看的是sys.path ,它返回的是一个列表,包含了若干个路径,它表示的是Python查找包的路径顺序,第一个是一个空字符串,它表示当前目录。之所以我们使用import 语句可以导入模块,靠的就是它。
sys.path
['',
'/Users/envs/py3/bin',
'/Users/envs/py3/lib/python36.zip',
'/Users/envs/py3/lib/python3.6',
'/Users/envs/py3/lib/python3.6/lib-dynload',
'/Users/envs/py3/lib/python3.6/site-packages',
'/Users/envs/py3/lib/python3.6/site-packages/pyspider-0.3.10-py3.6.egg',
'/Users/envs/py3/lib/python3.6/site-packages/setuptools-27.2.0-py3.6.egg',
'/Users/envs/py3/lib/python3.6/site-packages/IPython/extensions',
'/Users/.ipython']
~~~     # sys.argv 表示启动的时候传递给Python脚本的命令行参数。

import sys
if __name__ == '__main__':
print("Hello", end=' ')
if len(sys.argv) > 1:
print(' '.join(sys.argv[1:]))
~~~     # 上述是一个Python脚本hello.py 的代码,现在我们试着用不同的方式启动它

python hello.py
python hello.py Bill
python hello.py Mr Gates
~~~     # 我们会看到每次的输出不一样,再加两行代码,看一看sys.argv是什么?
~~~     # sys.argv是个列表

type(sys.argv)
print(sys.argv)

~~~     可以看到sys.argv是一个列表,它的第一个元素就是脚本的文件名。所以传递它的启动参数,都会放在列表的后面。我们可以使用这种方式接收用户传递的参数。

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

posted on   yanqi_vip  阅读(25)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示