模块初识
Python中模块又简称为“库”,库分为两种,一种为标准库,一种为第三方库。
标准库:不需要安装,可以直接导入,可以使用python的最常用功能。eg:getpass、os、sys
第三方库:必须要安装才能使用。eg:django 这个库必须安装才能用使用.
OS模块
1 >>> import os 2 >>> os.system('pwd') 3 /Users/sean/python/s14/zuoye/day2
os模块 V1
import os res = os.system('dir') print('--->',res) --------------------------- C:\>Python os.py 驱动器 C 中的卷没有标签。 卷的序列号是 7453-A691 C:\ 的目录 16/07/23 下午03:21 22 hello.py 16/08/02 下午01:30 52 os.py 09/07/14 上午11:20 <DIR> PerfLogs 11/04/12 下午10:57 <DIR> Program Files 16/07/29 下午06:20 <DIR> Program Files (x86) 16/07/20 下午12:02 <DIR> Python27 16/07/21 上午02:07 <DIR> Users 16/07/20 下午12:00 <DIR> Windows 2 个文件 74 字节 6 个目录 118,389,239,808 可用字节 ---> 0 #这里打印的为什么是个零呢? 而不是一个真正的dir的数据呢?这里要说一下了,system方法就是这样的,他只返回数据的执行结果是正确执行,还是错误执行,这里的0就表示命令执行成功,只要是非零就表示上面的命令执行失败。那有人该问了,我就想要命令的执行结果,不想要命令的执行状态,别急继续往下看。
os模块V2
import os res = os.popen('dir') #这里是用os的popen方法就会有你想要的了 print('--->',res)
看一下执行结果:
C:\>Python os.py
---> <os._wrap_close object at 0x002EF450> #what the fack! 这是打印的啥玩意,其实这是打印的返回数据的内存存放地址,如果想调出这个地址,还需要有如下一步
os模块V3
import os res = os.popen('dir').read() print('--->',res)
看一下执行结果:
#oh,yes!就是这个结果。
C:\>Python os.py ---> 驱动器 C 中的卷没有标签。 卷的序列号是 7453-A691 C:\ 的目录 16/07/23 下午03:21 22 hello.py 16/08/02 下午01:37 58 os.py 09/07/14 上午11:20 <DIR> PerfLogs 11/04/12 下午10:57 <DIR> Program Files 16/07/29 下午06:20 <DIR> Program Files (x86) 16/07/20 下午12:02 <DIR> Python27 16/07/21 上午02:07 <DIR> Users 16/07/20 下午12:00 <DIR> Windows 2 个文件 80 字节 6 个目录 118,386,798,592 可用字节
##注意##
上面的这种方法,在linux下我测试有问题,打印出来没有格式化输出。
os模块V4
这里再说一下os的另外两个方法,os.mkdir和os.mkdirs,前者是创建一个目录,后者是创建多级目录。可以尝试使用下!
sys模块
#!/usr/bin/env python import sys print (sys.argv) print (sys.argv[0]) print (sys.argv[1]) res = sys.argv print(res) bogon:day2 sean$ python import_os_argv.py start stop ['import_os_argv.py', 'start', 'stop'] import_os_argv.py start ['import_os_argv.py', 'start', 'stop']
可以看到sys.argv这个方法返回的是一个列表,如果想取出某个值,使用列表方法就能取到,关于列表的知识我们后面会继续讲。
上面都是标准库,我接下来也不会说第三方库,因为我也不会用;那我们自己就写一个简单的库,然后调用这个库,在说这个之前我们先说一下环境变量的事情。
我们调用一下sys模块,执行一下sys.path这个方法,看一下返回的数据。
>>> import sys >>> sys.path ['', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages']
我们能看到是一个列表的数据,其中有很多的路径元素,讲讲这些元素有什么用。
这个列表的整体作用是用在当用户执行导入一个模块的动作的情况下,python解释器会到这些相应的路径下寻找你的模块,如果找到那么顺利引用,如果没找到,
那么肯定报错喽!当然如果你引入模块写的绝对路径,他就不会使用这个参数进行模块导入了,第一个有的人会问了怎么是一个空路径,其实这个表示是在当前
目录查找的意思。下面我们来自己写一个模块尝试导入试试:
自己写个非常low的模块导入试试看:
1 bogon:day2 sean$ ls -l #查看一下当前目录下的文件 2 total 16 3 -rw-r--r-- 1 sean staff 42 8 2 11:27 import_os_argv.py 4 -rw-r--r-- 1 sean staff 47 8 2 11:26 print_module.py 5 bogon:day2 sean$ cat import_os_argv.py #查看一下执行文件 6 #!/usr/bin/env python 7 import print_module 8 bogon:day2 sean$ cat print_module.py #查看一下我写的简单模块内容 9 print('This is an example of a module import') 10 bogon:day2 sean$ 11 #当我引用这个模块的时候,模块的打印内容便输出到命令行了。 12 bogon:day2 sean$ python import_os_argv.py 13 This is an example of a module import
三元运算符
>>> a,b,c = 3,6,9 #这句话的意思是,如果 a>b 那么d就等于a,否则d就等于c >>> d = a if a > b else c >>> print(d) 9 >>>
>>> a,b,c = 3,6,9 #如果c>b那么d就等于a,否则d就等于c >>> d = a if c > b else c >>> print(d) 3 >>>
如果不使用这种方法,那么就的老老实实的写if...else ...了,是不是有点麻烦。
进制
二进制:01
八进制:01234567
十进制:0123456789
十六进制:0123456789ABCDEF
我们来做一下二进制与十六进制之间的转换:
我们把16进制的 BF873转化为二进制,首先我们要清楚二进制和十六进制之间的对照关系,如下:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0000 0001 0010 0011 0100 0101 0111 0111 1000 1001 1010 1011 1100 1101 1110 1111
那么这个十六进制的BF873是怎么转化成二进制呢?我们来讲一下规则,首先把每个数字都按照1拆4的规则进行拆分,如下:
B F 8 7 3
1011 1111 1000 0111 0011
那么最后的二进制为10111111100001110011 = BF873
需要补充的就是,如果有小数点的,小数点两边不能凑齐8位或者被8整除的位数,那么可以补零来进行换算,我们下面来换算一个2进制转换成16进制的例子
10101111001010.1011001
首先先看一下小数点左右是否可以被4整除,如果不能那么就用零来补充
0010 1011 1100 1010 . 1011 0010
2 B C A . B 2
那么最后的16进制就是2BCA.B2
bytes数据类型
在python2.0版本中,是不区分bytes类型和str类型的,二者存在隐转换的,所谓的隐式举个例子,在python2中如果用的数字大了,自动给你转成log了,但是在python3中不会这样了,要么报错,要么你手动的转换。所以说在python3.0里面二者是存在严格的区分的,也就是说你不能手动拼接字符串和数据包,也不能在
字节包里面搜索字符串(反之亦然)。
在python3中所有的字符串默认是Unicode编码,转换成任何编码只需要直接解码就好了。下面的图一定要牢记:
在python中二进制的数据都是bytes的数据类型,文本都是字符串的数据类型,
>>> msg = '我爱北京天安门' >>> print(msg) 我爱北京天安门>>> print (msg.encode('utf-8')) b'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\xe9\x 97\xa8' >>> b'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\x e9\x97\xa8'.decode('utf-8') '我爱北京天安门' >>>
列表
1.创建一个列表并默认输出所有列表元素
>>> name_list = ['sean','tom','jack','Angelia','Daisy','jack'] >>> print(name_list) ['sean', 'tom', 'jack', 'Angelia', 'Daisy', 'jack'] >>>
2.调出列表中的地2个元素‘tom’
#这里输入的1是表示tom所在列表中的下标
>>> print(name_list[1]) tom
我们可以查看一下tom的下标是不是为1,
>>> name_list.index('tom') 1
我们想为什么是1而不是2呢?这是因为计算机是从0开始计数的,第一个的下标也就是0了
3.列表的切片,我想取出列表的第二个到第五个的数据,也就是'tom','jack','Angelia','Daisy'这几个数据
#这里为什么是1:5而不是1:4呢?这里列表有一个原则学名叫做“左闭又开”,大白话就叫做“顾头不顾尾”,大概意思就是切片会吧开始的切上,结尾不会给切上的。
>>> print(name_list[1:5]) ['tom', 'jack', 'Angelia', 'Daisy']
#如果开头不写的话,默认就是从第一个元素开始取,也就是从下标为0的元素开始往外取
>>> print(name_list[:5]) ['tom', 'jack', 'Angelia', 'Daisy']
4.元素少的情况下,我们能知道最后一个元素是多少,所以可以直接拿到,但是当一个列表有2W+个元素的时候,甚至更多,我们该如何调取最后一个元素呢?
#这里的-1默认就是最后一个
>>> print(name_list[-1]) jack
那我们如果想取出倒数第一个到倒数第三个呢? 我们就要这么写了
#由于切片是左闭右开的原则,所以如果写成-3:-1那么最后一个元素将不被切出了。所以我们直接省略了-1
>>> print(name_list[-3:]) ['Angelia', 'Daisy', 'jack']
5.增加用户
第一种方法是直接追加到列表的最后位置
>>> name_list ['sean', 'tom', 'jack', 'Angelia', 'Daisy', 'jack'] >>> name_list.append('sary') >>> name_list ['sean', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary']
第二种方法是插入到指定位置,如果我想加一个用户为alex,把alex插到tom前面
#1的意思是插入到这个列表的什么位置,我们想插入到tom的前面,那插入后的下标是1,所以这里就写1
>>> name_list.insert(1,'alex') >>> name_list ['sean', 'alex', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary']
6.更改用户,现在把alex改为dave
#首先我们要先获取到alex这个名字的下标位置 >>> name_list.index('alex') 1 #然后把下标位置为1的名字改为dave >>> name_list[1] = 'dave' >>> name_list ['sean', 'dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary']
#连起来可以这样写
>>> name_list[name_list.index('alex')] = 'dave'
7.删除用户sean
删除总计有3种方法,无论使用那种方法 如果列表中指定的元素有多个,那么删除的将是最靠前的一个
#第一种删除的方法是制定元素名字
>>> name_list ['sean', 'dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary'] >>> name_list.remove('sean') >>> name_list ['dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary']
#这种方法也是可以的,但是这种方法如果不输入后面的下标[0],默认删除了这个列表,个人感觉存在危险,但是貌似提高B格
>>> name_list ['sean', 'dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary'] >>> del name_list[0] >>> name_list ['dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary']
#这种方法如果不指定删除的元素的下标,默认会删除最后一个元素。
>>> name_list ['sean', 'dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack', 'sary'] >>> name_list.pop() 'sary' >>> name_list ['sean', 'dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack'] >>> name_list.pop(0) ['dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack']
8.获取列表元素指定的某个元素下标
#如果列表中某个元素有两个或者多个,那么返回的下标为第一个元素的下标
>>> name_list ['sean', 'dave', 'tom', 'jack', 'Angelia', 'Daisy', 'jack'] >>> name_list.index('jack') 3
9.统计列表中某个元素有多少个
>>> name_list ['sean', 'dave', 'tom', 'Angelia', 'Daisy', 'jack', 'jack'] >>> name_list.count('jack') 2
10.反转这个列表的数据
>>> name_list ['jack', 'jack', 'Daisy', 'Angelia', 'tom', 'dave', 'sean'] >>> name_list.reverse() >>> name_list ['sean', 'dave', 'tom', 'Angelia', 'Daisy', 'jack', 'jack']
11.对列表进行排序,此排序是按照ASCII表进行排序的。
>>> name_list ['sean', 'dave', 'tom', 'Angelia', 'Daisy', 'jack', 'jack'] >>> name_list.sort() >>> name_list ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom']
12.把一个列表扩展到另外一个列表中
>>> name_list_2 = ['YunWei','KaiFa','ChanPin'] >>> name_list ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom'] >>> name_list.extend(name_list_2) >>> name_list ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin']
13.列表的“深浅cp”
我们知道列表中可以嵌套列表,也可以嵌套人和东西,但是它们并不是真正把小列表嵌套到里面,而是在这个地方指向的小列表的内存地址。
#####浅copy######
#查看一下name_list这个列表 >>> name_list ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin'] #向这个列表中插入一个列表[1,2,3] >>> name_list.append([1,2,3]) >>> name_list ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [1, 2, 3]] #copy namt_list 到 name_list_2,浅copy一共有四种方法,name_list_2 = copy.copy(name_list),name_list_2 = name_list[:],name_list_2 = list(name_list) >>> name_list_2 = name_list.copy() >>> name_list_2 ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [1, 2, 3]] >>> name_list ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [1, 2, 3]] #更改name_list中的第1个元素为xiaoxin >>> name_list[0] = 'xiaoxin' >>> name_list ['xiaoxin', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [1, 2, 3]] #我们看到更改了name_list后,name_list_2的第一个元素没有改变 >>> name_list_2 ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [1, 2, 3]] #把name_list中的最后一个列表元素中的第一个元素更改为4 >>> name_list[-1][0] =4 #此时我们发现两个列表中的列表元素全都变了 >>> name_list ['xiaoxin', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]] >>> name_list_2 ['Angelia', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]]
######深copy#######
#导入一个copy的模块
>>> import copy
#使用这个模块中的copy函数>>> name_list_2 = copy.deepcopy(name_list)
#两个列表是相同的 >>> name_list ['xiaoxin', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]] >>> name_list_2 ['xiaoxin', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]]
#分别更改第一个列表中第一个元素和小列表中的第一个元素,查看两个的区别 >>> name_list[0] = 'CeShi' >>> name_list ['CeShi', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]] >>> name_list_2 ['xiaoxin', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]] >>> name_list[-1][0] = 1 >>> name_list ['CeShi', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [1, 2, 3]] >>> name_list_2 ['xiaoxin', 'Daisy', 'dave', 'jack', 'jack', 'sean', 'tom', 'YunWei', 'KaiFa', 'ChanPin', [4, 2, 3]]
讲解一下为什么会出现这种状况:
由于列表后期存放的东西会超级大,那么我们假如真的复制了一个列表,这对系统的负载将是不敢想象的,所以python在这方面做了处理,如果列表中包含了列表那么复制这个列
表的情况只会复制第一层,也就是说下面的一层不会复制,如果还不明白,那我们就来看图
可能有人会问了,那这深浅copy到底有什么用呢?那我们来讲讲这个浅copy的用处,他可以用来做一个联合账号,看例子:
#首先做一个person的列表模版,里面放人和这个人的存款
>>> person = ['name',['money',100]] >>> p1 = person[:] >>> p2 = person[:] >>> p1 ['name', ['money', 100]] >>> p2 ['name', ['money', 100]]
#这里p1和p2是一个夫妻关系,当p1用户消费了50块钱,那么p2的帐号也消费了50块钱 >>> p1[0] = 'alex' >>> p2[0] = 'fenjie' >>> p1[1][1] = '50' >>> p1 ['alex', ['money', '50']] >>> p2 ['fenjie', ['money', '50']]
元组
元组一共有2个方法,分别为统计某个元素出现的次数和查询某个元素的下标
>>> mysql = ('Server IP','Server Passwd') >>> mysql.index('Server IP') 0 >>> mysql.count('Server IP') 1
列表练习
写一个购物车的程序
需求:
- 启动程序后,让用户输入工资,然后打印商品列表
- 允许用户根据商品编号购买商品
- 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
- 可随时退出,退出时,打印已购买商品和余额
1 # Author:Sean sir 2 shopping_list = [('Car', 20000), ('Iphone', 6999), ('MacBookPro', 12999), ('Alex python', 30), ('T-shirt', 199)] 3 shopping_cart_list = [] 4 salary = input('请问你的工资是多少: ') 5 if salary.isdigit(): 6 salary = int(salary) 7 elif salary == 'q': 8 exit() 9 else: 10 print('输入一个正确的工资格式吧!他应该是一个正整数的类型!') 11 while True: 12 for index, item in enumerate(shopping_list): 13 print(index, item) 14 user_choice = input('您要买啥呢?>>>') 15 if user_choice.isdigit(): 16 user_choice = int(user_choice) 17 if 0 <= user_choice < len(shopping_list): # 判断用户输入的是否大于0且小于总的产品数量 18 if salary > shopping_list[user_choice][1]: # 判断用户工资是否大于产品价格 19 salary -= shopping_list[user_choice][1] # 减掉总钱数 20 shopping_cart_list.append(shopping_list[user_choice][0]) # 把产品加入购物车的列表 21 22 else: 23 print('都没钱了,\033[31;1m汪哥\033[0m都急眼了,还买个屁啊!') 24 else: 25 print('请守规矩,输入一个正确的产品编号吧!不然没得玩了!') 26 elif user_choice == 'q': 27 print('您成功购买了如下产品:') 28 for product in shopping_cart_list: 29 print(product) 30 print('您的钱包还剩%s,请斟酌您的开支!' %salary) 31 break 32 else: 33 print('请守规矩,输入一个正确的产品编号吧!不然没得玩了!-->')