.pyc是什么?
执行Python代码时,如果导入了其他的 .py 文件,那么,执行过程中会自动生成一个与其同名的 .pyc 文件,该文件就是Python解释器编译之后产生的字节码。如果pyc文件与py文件修改时间相同,才会读取pyc文件,否则,Python就会读原来的py文件。
其实并不是所有的.py文件在与运行的时候都会差生.pyc文件,只有在py文件import相应的.py文件的时候,并且被import的.py文件没有执行过,才会生成相应的.pyc文件
ps:代码经过编译可以产生字节码;字节码通过反编译也可以得到代码。
数据类型
- 数字
- int(整型)
- float(浮点型)
- complex(复数)
- 布尔值(0 or 1)
- 字符串
注: Python存在小数池: -5~256
>>> b=257 #257,内存地址不同
>>> a=257
>>> id(a)
57594912
>>> id(b)
57594960
>>> b=256 #256,内存地址相同
>>> a=256
>>> id(b)
259737840
>>> id(a)
259737840
三元运算
result = 值1 if 条件 else 值2
如果条件为真:result = 值1
如果条件为假:result = 值2
字符串操作
特性:不可修改
string='my Name is ZhuYuLiang'
string.capitalize() #把字符串的第一个字符大写,其余小写
输出:'My name is zhuyuliang'
string.center(30,'-') #返回一个原字符串居中,并使用 空格[默认] 填充至长度width的新字符串
输出:'----my Name is ZhuYuLiang-----'
string.count('u') #返回'u'在string里面出现的次数
输出:2
string.endswith('ang') #检查字符串是否以ang结束
输出:True
string.find('u') #检测u是否包含在string中,返回最左面索引,不存在返回-1
输出:13
string.rfind('u') #检测u是否包含在string中,返回最右面的索引,不存在返回-1
输出:15
string.index('c') #跟find()方法一样,只不过如果str不在string中会报一个异常.
输出:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
string.isalnum() #如果string至少有一个字符并且所有字符都是字母或数字则返回True,否则返回False
输出:False #因为有空格
string.isalpha() #如果string至少有一个字符并且所有字符都是字母则返回True,否则返回False
输出:False #因为有空格
string.isnumeric() #如果string中只包含数字字符,则返回True,否则返回False
输出:False #因为有空格
'-'.join('123') #以任意字符,作为分隔符,将seq中所有的元素(字符串表示)合并为一个新的字符串
输出:'1-2-3'
string.rjust(30,"*") #返回一个原字符串右对齐,并使用*填充至长度width的新字符串
输出:'*********my Name is ZhuYuLiang'
string.ljust(30,"*") #返回一个原字符串左对齐,并使用*填充至长度width的新字符串
输出:'my Name is ZhuYuLiang*********'
string.lower() #转换string中所有大写字符为小写.
输出:'my name is zhuyuliang'
max(string) #返回字符串string中最大的字母,是根据ASCLL码来排序的。
输出:'y'
min(string) #返回字符串str中最小的字母,是根据ASCLL码来排序的。
输出:' ' #空格的ASCLL码排在第32位
string.replace('u','Z',2) #把string中的u替换成Z,2替换次数。
输出:'my Name is ZhZYZLiang'
string.split(" ",2) #以" "为分隔符切片string,'2'切割次数,分割完为列表。
输出:['my', 'Name', 'is ZhuYuLiang']
string.startswith('N',3,6) #检查字符串是否是以N开头,是则返回True,否则返回False。3~6在指定范围内检查.
输出:True
string.swapcase() #翻转string中的大小写
输出:'MY nAME IS zHUyUlIANG'
string.upper() #转换string中的小写字母为大写
输出:'MY NAME IS ZHUYULIANG'
string.zfill(30) #返回长度为30的字符串,原字符串string右对齐,前面填充0
输出:'000000000my Name is ZhuYuLiang'
string.strip() #移除元素两侧的空格,\t,\n等都可以去除掉
>>> str='\nabc\r\n'
>>> str.strip()
'abc'
string.lstrip() #移除左面元素的空格
>>> a='\nc\nb\n'
>>> a.lstrip()
'c\nb\n'
string.rstrip() #移除右面元素的空格
>>> a='\nc\nb\n'
>>> a.rstrip()
'\nc\nb'
len(string) #统计一个字符串长度
输出:21
string.isdigit() #判断字符串是否只由数字组成。
输出:False
string.title() #所有单词的首字母大写其余小写。
输出:'My Name Is Zhuyuliang'
string.isidentifier #判断是否是一个合法的标识符,变量名。
输出:False #因为有空格
string.isupper #是否全部为大写。
输出:False
Maketrans #加密字符串
>>> intab='mZL' #这是具有实际字符的字符串。
>>> outtab='123' #这是具有相应映射字符的字符串,需要一一对应,数量不能有误差
>>> trantab=str.maketrans(intab,outtab)
>>> string.translate(trantab)
'1y Name is 2huYu3iang' #结果被定义好的规则替换了
列表
定义列表
names=['zyl','cl','lxl']
通过下标访问列表中的元素,下标从0开始计数
>>> names[0]
'zyl'
>>> names[2]
'lxl'
>>> names[-2]
'cl'
切片:取多个元素,列表切片是从左到右来切的。
>>> names[1:2] #取下标1至下标2之间的内容,包括1,不包括2
['cl']
>>> names[0:-1] #取下标0至-1的值,不包括-1
['zyl', 'cl']
>>> names[:-1] #如果是从头开始取,0可以忽略,跟上句效果一样
['zyl', 'cl']
>>> names[1:] #如果想取最后一个,必须不能写-1
['cl', 'lxl']
>>> names[:] #取出所有内容
['zyl', 'cl', 'lxl']
>>> names[::2] #后面的2是代表,每隔一个元素,就取一个
['zyl', 'lxl']
追加
>>> names
['zyl', 'cl', 'lxl']
>>> names.append("libinbin")
>>> names
['zyl', 'cl', 'lxl', 'libinbin']
修改
>>> names
['zyl', 'cl', 'lxl', 'libinbin']
>>> names[1]='zyl2'
>>> names
['zyl', 'zyl2', 'lxl', 'libinbin']
删除
>>> names
['zyl', 'cl', 'lxl', 'libinbin']
>>> names[1]='zyl2'
>>> names
['zyl', 'zyl2', 'lxl', 'libinbin']
>>> del names[2]
>>> names
['zyl', 'zyl2', 'libinbin']
>>> names.remove('zyl2') #删除指定元素
>>> names
['zyl', 'libinbin']
>>> names.pop() #弹出最后一个值,有返回值
'libinbin'
>>> names
['zyl']
>>>
扩展
>>> names
['zyl']
>>> b=[1,2,3]
>>> names.extend(b)
>>> names
['zyl', 1, 2, 3]
拷贝
内存地址完全相同的拷贝
>>> names
['zyl', 1, 2, 3]
>>> b=names
>>> names[1]=2
>>> names
['zyl', 2, 2, 3]
>>> b
['zyl', 2, 2, 3]
浅拷贝:只拷贝第一层内容,剩下的拷贝共用第二层内存地址
>>> import copy
>>> names=['zyl',[1]]
>>> a=names[:] #方法一
>>> b=names.copy() #方法二
>>> c=copy.copy(names) #方法三
>>> d=list(names) #方法四
>>> names[1][0]=2
>>> print(a,b,c,d,names)
['zyl', [2]] ['zyl', [2]] ['zyl', [2]] ['zyl', [2]] ['zyl', [2]]
深拷贝:内存地址完全不同
>>> e=copy.deepcopy(names)
>>> names[1][0]='qq'
>>> names
['zyl', ['qq']]
>>> e
['zyl', [2]]
统计
>>> names=[1,2,3,1,1]
>>> names.count(1)
3
排序&反转
排序:
>>> names
[1, 2, 3, 1, 1]
>>> names.sort()
>>> names
[1, 1, 1, 2, 3]
反转:
>>> names.reverse()
>>> names
[3, 2, 1, 1, 1]
获取下标
>>> names
[3, 2, 1, 1, 1]
>>> names.index(1)
2
#只返回找到的第一个下标
注:sort排序是根据ASCLL码来排序的。
元组
元组其实跟列表差不多,也是存一组数,只不过它一旦创建,便不能再修改
names = ("alex","jack","eric")
它只有2个方法,一个是count,一个是index。
注:如果只有一个值结尾要加“,”
字典
字典一种key - value 的数据类型
语法:
info = {
'a': "a1",
'b': "b2",
'c': "c3",
}
特性:
- 字典是无序的
- key必须唯一,所以天生去重
增加
>>> info['d']='d4'
>>> info
{'a': 'a1', 'b': 'b2', 'c': 'c3', 'd': 'd4'}
注:假如是列表的话,这一步只能为替换,不能新添加
修改
>>> info['d']='d5'
>>> info
{'a': 'a1', 'b': 'b2', 'c': 'c3', 'd': 'd5'}
删除
>>> info
{'a': 'a1', 'b': 'b2', 'c': 'c3', 'd': 'd4'}
>>> info.pop("a") #方法一,有返回值
'a1'
>>> del info['b'] #方法二,无返回值
>>> info
{'c': 'c3', 'd': 'd4'}
>>> info.popitem() #方法三,随机删除
('d', 'd4')
查找
>>> info
{'c': 'c3'}
>>> info.get('c') #获取
'c3'
>>> info.get('d')
>>> info['c'] #同上,但是看下面
'c3'
>>> info['d'] #如果一个key不存在,就报错,get不会,不存在只返回None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'd'
多级字典嵌套及操作
>>> city_dict = {'广州': {'天河': ['天河体育馆', '金山大夏'],
... '越秀': ['越秀公园', '光孝寺'],
... '番禺': ['长隆欢乐世界', '大夫山']},
... '佛山': {'禅城': ['梁园', '孔庙'],
... '南海': ['千灯湖', '南国桃园'],
... '顺德': ['清晖园', '西山庙']}}
>>> city_dict['佛山']['顺德'][1]+=',有佛像'
>>> city_dict['佛山']['顺德'][1]
'西山庙,有佛像'
其他操作
#获取所有值
>>> info.values()
dict_values(['a1', 'b2', 'c3'])
#获取所有键
>>> info.keys()
dict_keys(['a', 'b', 'c'])
#如果键不存在则为添加,存在则不做操作
>>> info.setdefault('d','d4')
'd4'
>>> info.setdefault('a','a2')
'a1'
>>> info
{'a': 'a1', 'b': 'b2', 'c': 'c3', 'd': 'd4'}
#将其他列表,添加到当前列表,如果key存在则为修改
>>> info
{'a': 'a1', 'b': 'b2', 'c': 'c3', 'd': 'd4'}
>>> info2={1:2,'a':'a2'}
>>> info.update(info2)
>>> info
{'a': 'a2', 'b': 'b2', 'c': 'c3', 'd': 'd4', 1: 2}
#将字典以列表嵌套元组的方式返回
>>> info.items()
dict_items([('a', 'a2'), ('b', 'b2'), ('c', 'c3'), ('d', 'd4'), (1, 2)])
#生成默认dict
>>> dict.fromkeys([1,2,3],'test')
{1: 'test', 2: 'test', 3: 'test'}
循环dict
#方法1
for key in info:
print(key,info[key])
#方法2
for k,v in info.items(): #会先把dict转成list,占内存,数据里大时莫用
print(k,v)
集合操作
集合是一个无序的,不重复的数据组合,它的主要作用如下:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
常用操作
a = set("Hello") #创建一个唯一字符的集合
s = set([3,5,9,10]) #创建一个数值集合
t = set([1,2,3,5])
>>> print(t|s) #t 和 s的并集
{1, 2, 3, 5, 9, 10}
>>> print(t&s) #t 和 s的交集
{3, 5}
>>> print(t-s) #求差集(项在t中,但不在s中)
{1, 2}
>>> print(t^s) #对称差集(项在t或s中,但不会同时出现在二者中)
{1, 2, 9, 10}
#添加
>>> t.add(10) #添加一项
>>> t.update([11,12,13]) #添加多项
#删除
>>> t.remove(13)
>>> t.pop() #随机删除
>>> t.discard(14) #如果被删除的值不存在,不会报错
#长度
>>> len(t)
7
#测试12是否是t的成员
>>> 12 in t
True
#测试12是否不是t的成员
>>> 12 not in t
False
拷贝
s.copy()
每日练习
程序:购物车程序
需求:
用户入口:
- 启动程序后,让用户输入工资,然后打印商品列表
- 允许用户根据商品编号购买商品
- 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
- 可随时退出,退出时,打印已购买商品和余额
- 商品信息存在文件中
- 记录用户已经购买商品,余额记录
商家入口:
- 可以添加商品,修改商品价格
代码如下:
import json
import os
commodity=[
('电脑',9888),
('鼠标',300),
('游艇',4500),
('苹果X',11888)
]
def write_file(file,info):
'''
调用此函数时需要传入文件路径和文件内容
:param file:
:param info:
:return:
'''
with open(file,'w') as f:
f.write(json.dumps(info))
return True
def read_file(file):
'''
调用此函数时需要传入文件路径,返回文件转义后的文件内容
:param file:
:return:
'''
with open(file, 'r') as f:
info=json.loads(f.read())
return info
def initial_commodity():
'''
商品文件不存在则写入,然后读取
:return:
'''
if not os.path.exists('./commodity_list.json'):
write_file('./commodity_list.json',commodity)
commodity_list=read_file('./commodity_list.json')
return commodity_list
def salary_mod(name,user_info):
'''
此函数用于user.json文件不存在,或者用户名不存在与user.json文件,
user_info是一个内存地址是从父级函数传入的,在此函数中修改父级函数中的
user_info也会发送变化。
:param name:
:param user_info:
:return:
'''
salary = input('请输入工资: ')
if not salary.isdigit():
print('\033[31;1m输入非数字,请重新输入!\033[0m')
return salary_mod(name,user_info)
salary=int(salary)
count=0
while count <3:
passwd=input('请输入密码: ')
again_passwd=input('请再次输入密码:')
if passwd != again_passwd:
print('\033[31;1m两次密码不相等!\033[0m')
count += 1
continue
else:
break
else:
print('\033[31;1m密码重试次数过多,退出程序!\033[0m')
exit()
user_info[name]=[salary,passwd,[]]
write_file('./user.json',user_info)
def print_commodity():
'''
从文件中读取商品列表,然后打印
:return:
'''
commodity_list=initial_commodity()
print('现有商品,如下'.center(50, '+'))
for index, commodity in enumerate(commodity_list):
print(index, end=' ')
for i in commodity:
print(i, end=' ')
print()
return commodity_list
def authentication_user():
'''
用户认证函数,用户不存在则创建。
:return:
'''
if not os.path.exists('./user.json'):
name=input('请输入用户名:')
user_info={}
salary_mod(name,user_info)
return user_info,name
else:
user_info=read_file('./user.json')
name = input('请输入用户名:')
if name not in user_info:
salary_mod(name,user_info)
return user_info,name
else:
count=0
while count <3:
passwd=input('请输入密码: ')
if passwd == user_info[name][1]:
print('欢迎登陆{}用户,账户余额为:{}'.format(name,user_info[name][0]))
del user_info[name][2][:] #清空购物车
return user_info,name
else:
print('\033[31;1m密码错误请重试!\033[0m')
count+=1
continue
else:
print('\033[31;1m密码错误次数过多,退出程序!\033[0m')
exit()
def user():
'''
用户视角主函数,购买商品然后扣费
:return:
'''
info=authentication_user()
user_info=info[0]
name=info[1]
if not user_info:exit()
while True:
commodity_list=print_commodity()
use_choice=input("选择要购买的商品编号: ")
if use_choice.isdigit():
use_choice=int(use_choice)
elif use_choice == 'q':
print('余额为: {}商品为:{}'.format(user_info[name][0],user_info[name][2][:]))
write_file('./user.json',user_info)
break
else:
print('\033[41;1m输入错误,重新选择\033[0m')
continue
if use_choice >= 0 and use_choice <= len(commodity_list)-1:
if user_info[name][0] > commodity_list[use_choice][1]:
user_info[name][0]-=commodity_list[use_choice][1]
user_info[name][2].append(commodity_list[use_choice][0])
print('购买成功,余额为: {}'.format(user_info[name][0]))
else:
print('\033[31;1m余额不足\033[0m')
else:
print('\033[31;1m选择的商品不存在\033[0m')
def merchant():
'''
商家视角主函数,可添加商品和修改商品价格
:return:
'''
while True:
commodity_list=print_commodity()
use_choice=input('添加商品请输入1,修改商品价格请输入2: ')
if use_choice == '1':
add_commodity=input('输入商品名称:')
while True:
commodity_prices=input('输入商品价格:')
if not commodity_prices.isdigit():
print('价格输入错误,请重新输入')
continue
else:
commodity_list.append((add_commodity,int(commodity_prices)))
write_file('./commodity_list.json', commodity_list)
break
elif use_choice == '2':
judge=True
while judge:
add_commodity = input('输入要修改的商品序号:')
if not add_commodity.isdigit():
print('\033[31;1m输入的非数字\033[31;0m')
continue
add_commodity=int(add_commodity)
if not add_commodity >= 0 and add_commodity <= len(commodity_list):
print('\033[31;1m商品序号输入错误,请重新输入:\033[31;0m')
continue
else:
while judge:
commodity_prices=input('输入商品价格:')
if not commodity_prices.isdigit():
print('价格输入错误,请重新输入')
continue
else:
commodity_list[add_commodity]=(commodity_list[add_commodity][0],int(commodity_prices))
write_file('./commodity_list.json', commodity_list)
judge=False
elif use_choice == 'q':
break
else:
print('\033[31;1m输入错误,请重新选择\033[0m')
continue
if __name__ == '__main__':
while True:
print('''
1.用户视角
2.商家视角
''')
choice=input('选择视角:')
if choice == '1':
user()
break
elif choice == '2':
merchant()
break
else:
print('输入错误,请重新选择')
continue