day08_雷神_模块一

时间:2022-02-28 04:29:20

day08


一、模块

回顾相关:

取值顺序:

  在局部调用:局部命名空间->全局命名空间->内置命名空间

  在全局调用:全局命名空间->内置命名空间

内置函数: globals(),locals()
globals():返回一个字典,字典里面的内容是全局作用域的内容。
locals():返回一个字典,当前位置 的所有变量。 关键字 global, nonlocal
global:引用并且改变一个全局变量
在局部作用域声明一个全局变量
nonlocal: 不能操作全局变量
在哪一层引用得,就从该层开始全部改变。

1. 什么是模块

最常常见的场景,一个模块就是包含了一组功能的python文件,例如module.py,模块名是module
可以使用import module,四个通用类别:
  1 使用python编写的.py文件   2 已被编译为共享库或DLL的C或C++扩展   3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)   4 使用C编写并链接到python解释器的内置模块

2. 为什么要用模块

1、从文件级别组织程序,更方便管理
2、拿来主义,提升开发效率

3. 如何使用模块-》import spam

1、第一次导入模块,会发生3件事,重复导入只会引用之前加载好的结果,不会再次运行代码。

1、产生一个新的名称空间
2、运行spam.py代码,产生的名字都存放于1的名称空间中,运行过程中global关键字指向的就是该名称空间
3、在当前名称空间拿到一个名字spam,该名字指向1的名称空间
引用spam.py中名字的方式:spam.名字 强调:被导入的模块在执行过程中使用自己独立的名称空间作为全局名称空间

2、起别名:import spam as sm,两种情况下使用

1.被导入模块名字比较长;

2.  engine=input('>>: ')
if engine == 'mysql':
import mysql as sql
elif engine == 'oracle':
import oracle as sql
sql.parse()
统一代码后部分的调用方式。

3、一行导入多个模块:import time,sys,spam

4、如何使用模块-》from 模块名 import 名字

    优点:引用时不用加前缀,简单
缺点:容易与当前名称空间的名字冲突 from spam import money as m from spam import money,read1,read2,change from spam import * #*包含除了下划线开头以外所有的名字,一个下划线 __开头__结尾的都是内置的。特定功能的。

示例:

__all__=['read1','read2','_money'] # 如果定义了__all__,*就是指这个列表里的名字。_money也可以访问到。

_money=1000 默认*不能访问到下划线开头的名字

5、一个python文件的两种用途

name

1、当做脚本执行:__name__ == '__main__'
2、当做模块被导入使用:__name__ == '模块名' if __name__ == '__main__':
pass

变量总结

类中: 一般你想查询全部的静态变量时,用__dict__ 其他全部都用类名.变量名。

内置函数: globals(),locals()
globals():返回一个字典,字典里面的内容是全局作用域的内容。
locals():返回一个字典,当前位置 的所有变量。 dir(): 当前模块的所有属性列表,就是globals函数的key值。 函数的有用信息:
print(login.__doc__) 返回函数注释内容。
print(login.__name__) 返回函数的名字。

6、 模块的搜索路径

搜索顺序:
内存--->内置模块--->sys.path 路径

二、包

1、什么是包

包就是一个包含了__init__.py文件的文件夹(可以往该文件夹下放一堆子模块)

为什么有__init__:
import导入,做的三件事不会变化,首先开辟一个名称空间,执行包的.py文件,就是执行这个__init__文件。

2、 包的使用

注意:但凡是在导入时,出现.,这是导入包才有的语法,.的左边必须是一个包,使用的时候没有这种限制

注意:包的目录结构是开发者自己定义的,使用者不需要知道,所以,不要使用的时候直接把目录都添加到sys.path里。

3、 绝对导入:

都是从同一个*目录导入的,缺点是这个目录名字改变之后,所有都要跟着改。

from package1.m1 import f1
from package1.package2.m2 import f2 使用者只需要: import package1 package1.f1()
package1.f2()

4、 相对导入

1.
from .m1 import f1
from .package2.m2 import f2 一个.是当前,.. 是上级,再多一个点又是再上级目录。 2.
当包跟执行文件不在同一*目录下,
只需要:
import sys 添加包所在目录的路径到sys.path。其余都一样
sys.path.append(r'D:\video\python20期\day5\02_包\测试三(相对导入)\aaa') import package1
package1.f2()

三、软件开发目录规范

bin 存放一些执行文件,整个程序的入口
start.py
conf 配置文件
settings.py
lib 库,自己写的模块、包等,或者网上下载的
常用工具等,
commom.py
sql.py
core 核心逻辑
src.py
log 日志
access.log
db 数据库相关
user
Reandme 先写核心逻辑

四、 collections模块

collecctions模块是扩展我们数据类型的一个模块, 在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

1.namedtuple: 生成可以使用名字来访问元素内容的tuple

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2

类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

#namedtuple('名称', [属性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r']) from collections import namedtuple
circle = namedtuple('一个圆形',['x','y','r'])
c = circle(1,2,3)
print(c.r) # 3

队列、栈的概念

deque是为了高效实现插入和删除操作的双向列表,使用于队列和栈

在存储数据的基础上 严格的维持了一个秩序,数据的进出顺序
queue 队列 先进来的先出去 —— 售票
栈 先进来的后出去 —— 计算机的计算、算法

queue 队列

import queue # 队列
q = queue.Queue()
# l = list()
q.put(1) # 放
q.put(2) # 放
print(q.get()) # 取 1
print(q.get()) # 2

deque

import collections
dq = collections.deque()
dq.append(1)
dq.append(2)
dq.append(3) # 默认添加到右边
dq.appendleft(5) #添加到左边
print(dq.pop()) # 默认删除右边的
print(dq.popleft())
print(dq) # deque([5, 1, 2])
print(dq[0]) # 5
print(dq[2]) # 2

dict

>>>dict()                        # 创建空字典
{}
>>> dict(a='a', b='b', t='t') # 传入关键字
{'a': 'a', 'b': 'b', 't': 't'}
>>> dict(zip(['one', 'two', 'three'], [1, 2, 3])) # 映射函数方式来构造字典
{'three': 3, 'two': 2, 'one': 1}
>>> dict([('one', 1), ('two', 2), ('three', 3)]) # 可迭代对象方式来构造字典 # 一个列表的可迭代对象
{'three': 3, 'two': 2, 'one': 1}
>>>

defaultdict

有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。

即: {'k1': 大于66 , 'k2': 小于66}

values = [11, 22, 33,44,55,66,77,88,99,90]
dict = {'key1':[],'key2':[]}
for i in values:
if i < 66:
dict['key1'].append(i)
else:
dict['key2'].append(i)
print(dict)

示例1:

#def func():return 5
#dd = defaultdict(func) >>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A') 设置默认值
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'

示例2:

dd = defaultdict(list)
print(dd) # defaultdict(<class 'list'>, {})
print(dd['a']) # []
dd['aaaaaaaaa'].append(1)
dd['aaaaaaaaa'].append(2)
print(dd) # defaultdict(<class 'list'>, {'a': [], 'aaaaaaaaa': [1, 2]})

五、 time模块

常用方法
1.time.sleep(secs)
(线程)推迟指定的时间运行。单位为秒。 2.time.time()
获取当前时间戳

时间的几种表示方式

为什么要有时间戳时间 —— 计算机用的float
格式化时间 —— 人用的 年月日时分秒 str print(time.strftime('%Y')) # year
print(time.strftime('%m')) # month
print(time.strftime('%d')) # day print(time.strftime('%H')) # hour
print(time.strftime('%M')) # Minute
print(time.strftime('%S')) # Second print(time.strftime('%c')) # Thu Jul 5 10:29:31 2018
print(time.strftime('%m/%d/%Y %H:%M')) # year 时间戳时间float —— 给机器看的
结构化时间 —— 中间的过渡
格式化 %s —— 给人看的

时间元组:localtime将一个时间戳转换为当前时区的struct_time

时间戳时间转换为结构化时间
print(time.localtime(1500000000))
结果: time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)

结构化时间转换为时间戳时间

time_tuple = time.localtime(15000000000)
print(time.mktime(time_tuple))

结构化时间-->字符串时间

#time.strftime("格式定义","结构化时间")  结构化时间参数若不传,则现实当前时间

>>>time.strftime("%Y-%m-%d %X")
'2017-07-24 14:55:36'
>>>time.strftime("%Y-%m-%d",time.localtime(1500000000))
'2017-07-14'

字符串时间-->结构化时间

#time.strptime(时间字符串,字符串对应格式)

>>>time.strptime("2017-03-16","%Y-%m-%d")
time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
>>>time.strptime("07/24/2017","%m/%d/%Y")
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)

六、 random模块

0-9    数字
65-90 大写字母
97-122 小写字母

常用命令:

>>> import random
#随机小数
>>> random.random() # 大于0且小于1之间的小数
0.7664338663654585
>>> random.uniform(1,3) #大于1小于3的小数
1.6270147180533838
#恒富:发红包 #随机整数
>>> random.randint(1,5) # 大于等于1且小于等于5之间的整数
>>> random.randrange(1,10,2) # 大于等于1且小于10之间的奇数 #随机选择一个返回
>>> random.choice([1,'23',[4,5]]) # #1或者23或者[4,5]
#随机选择多个返回,返回的个数为函数的第二个参数
>>> random.sample([1,'23',[4,5]],2) # #列表元素任意2个组合
[[4, 5], '23'] #打乱列表顺序
>>> item=[1,3,5,7,9]
>>> random.shuffle(item) # 打乱次序
>>> item
[5, 1, 3, 7, 9]
>>> random.shuffle(item)
>>> item
[5, 9, 7, 1, 3]

生成一个6位数的随机数,包含数字、大小写字母

import random

def v_code():

    code = ''
for i in range(5): num=random.randint(0,9)
alf=chr(random.randint(65,90))
add=random.choice([num,alf])
code="".join([code,str(add)]) return code print(v_code()) 或者: def random_code(num,alpha=True):
import random
code = ''
for i in range(num):
choice = str(random.randint(0,9))
if alpha:
alpha_upper = chr(random.randint(65,90))
alpha_lower = chr(random.randint(97,122))
choice = random.choice([choice,alpha_lower,alpha_upper])
code += choice
return code print(random_code(9))

七、 sys模块

sys.path

返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

sys.version 获取Python解释程序的版本信息

sys.platform 返回操作系统平台名称

print('3.6' in sys.version)  # True
print(sys.platform) # win32

print(sys.modules)

记载了我们已经导入的模块名以及这个模块的内存地址

print("sys" in sys.modules)  #  True

sys.args,命令行参数List,第一个元素是程序本身路径

if len(sys.argv)>1 and sys.argv[1] == 'alex'and sys.argv[2] == 'alex3714':
print('登陆成功')
else:
user = input('user:') # 阻塞
pwd = input('pwd:')
if user == 'alex' and pwd == 'alex3714': print('登陆成功') print(sys.argv) 注意: 需要在外部执行 比如cmd,里执行,拷贝该文件路径,输入两个实参。 C:\Users\Administrator>python C:\Users\Administrator\Desktop\oldboy_python\day8\7.sys模块.py alex alex3714
登陆成功
['C:\\Users\\Administrator\\Desktop\\oldboy_python\\day8\\7.sys模块.py', 'alex', 'alex3714']

八、 os模块

os模块是与操作系统交互的一个接口

工作目录相关

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
print(os.getcwd())
所谓工作目录并不是当前文件所在的位置
而是执行代码的时候我的目录 __file__ 当前文件所在的绝对路径永远是 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')

文件夹、文件相关

os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息

和不同操作系统的差异有关系

os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

在python中执行操作系统命令

os.system("bash command")  运行shell命令,直接显示
os.popen("bash command").read() 运行shell命令,获取执行结果
os.environ 获取系统环境变量 print(os.system('tasklist')) # 会乱码,一般不这么用 a = os.popen("tasklist").read()
print(a)

os.path

os.path.abspath(path) 返回path规范化的绝对路径

获取当前文件所在目录
import os
print(os.path.abspath('.'))
print(os.path.dirname(__file__)) os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小 print(os.path.join('C:','D:\\','dir1','dir2','a.txt'))
# print(os.path.join('D:\\','dir1','dir2','a.txt')) # print(os.path.normcase('c:/windows\\SYstem32\\..'))
# print(os.path.normpath('c://windows\\System32\\../Temp/')) #C:\windows\temp #F:\Python周末20期\day6\3 os模块.py\..\..
# print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) BASE_DIR=os.path.normpath(os.path.join(
os.path.abspath(__file__),
'..',
'..'
))
print(BASE_DIR) # print(os.path.getsize(r'F:\Python周末20期\day6\1 本节内容'))

九、 正则模块

字符组 : [字符组]

[0-9]-----7-----True

也可以用-表示范围,[0-9]就和[0123456789]是一个意思

[a-z]-----s-----True

同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示

[A-Z]-----B-----True

[A-Z]就表示所有的大写字母

[0-9a-fA-F]-----e-----True

可以匹配数字,大小写形式的a~f,用来验证十六进制字符

元字符,元字符就是只会匹配一个字符。

匹配内容
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W
匹配非字母或数字或下划线
\D
匹配非数字
\S
匹配非空白符
a|b
匹配字符a或字符b
()
匹配括号内的表达式,也表示一个组
[...]
匹配字符组中的字符
[^...]
匹配除了字符组中字符的所有字符

量词:

量词
用法说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

re.findall

import re
ret = re.findall('\d+(\.\d+)?', 'eva45.65+346[55] egon 35yuan15')
print(ret)
# ['.65', '', '', '', ''] import re
ret = re.findall('\d+(?:\.\d+)?', 'eva45.65+346[55] egon 35yuan15')
print(ret)
['45.65', '346', '55', '35', '15']

?总结:

?做量词 表示0次或1次
?在量词后 表示惰性匹配
?:在分组开头 表示取消分组优先 (re.findall())

re.search

ret = re.search('(\d)5', 'eva4565346 egon 35yuan15')
print(ret)
if ret:
print(ret.group())
print(ret.group(0))
print(ret.group(1))
print(ret.group(2))
在search中没有正则规则的分组优先显示功能