函数默认值参数、全局变量、深拷贝、可变参数、关键字参数、json模块使用、time模块操作
#内置函数:
input()函数接受一个标准输入数据,返回为 string 类型。
print() 方法用于打印输出,最常见的一个函数。
int() 函数用于将一个字符串或数字转换为整型
round() 方法返回浮点数x的四舍五入值。
列表生成式:
s=[1,2,3,4,5,6,7,8,9]
for i in s:
print(i+1)
res=[i+1 for i in s]
print(res)
print([i+1 for i in s])
res1=[str(i) for i in s]#变成字符串
print(res1)
#列表生成式可以简化循环
在函数里面用return和在函数里面print的区别
#方式一:没有return只有print的话是没有办法拿到这个值,只能看
def funtion1(a,b):
res=a+b
print(res)
funtion1(1,2)
#方式二:有return只以用来看也可以拿到这个值
def funtion2(a,b):
res=a+b
return res
res=funtion2(1,2)
print(res)
def get_user():
s='abc,123'
username,userpassword=s.split(',')
return username,userpassword#返回多个值可以用一个变量来接收,返回的是一个元组,得用下标来取值
# res=get_user()
# print(res)
def login():
for i in range(3):
name,password=get_user()#调用上面的函数
name1=input('请输入用户名:')
password1=input('请输入密码:')
if name==name1 and password==password1:
print('登录成功')
return
else:
print('登录失败!')
login()
#写函数的时候,函数的功能不可以太复杂,如果功能复杂就拆分出来
#函数:
# return的作用:
# 1、把函数处理的结果返回
# 2、结束函数,函数里遇到return,函数立即结束
# import random
# def phone(count):
# count=int(count)
# if count<1:
# print('执行')
# return
# print('没执行')
# dict=set()
# while len(dict) !=count:
# start = ['150','130', '158', '138']
# res_start = random.choice(start)
# end = random.randint(0, 99999999)
# res = '%s%08d\n'%(res_start, end)
# dict.add(res)
# with open('hh', 'a+', encoding='utf-8')as fr:
# fr.writelines(dict)
# return dict
# count=input('请输入你想产生的条数')
# res1=phone(count)
# print(res1)
函数默认值参数
默认参数:
默认参数就是在定义形参的时候,给函数默认赋一个值,比如说数据库的端口这样的,默认给它一个值,这样就算你在调用的时候没传入这个参数,它也是有值的
so,默认参数不是必填的,如果给默认参数传值的话,它就会使用你传入的值。如果使用默认值参数的话,必须放在位置参数后面定义。
1
2
3
4
|
def conn_mysql(user,passwd,port=3306):#定义一个连接mysql的方法,虽然这个方法并没有连接mysql,我只是举个默认值参数的例子,port就是一个默认值参数
print(user,passwd,port)
coon_mysql('root','123456')#没指定默认值
coon_mysql('root','123456',port=3307)#指定默认值参数的值
|
def say(word='haha'):#参数后面等于一个默认值,如果变量没传东西,会默认一个参数,如果传了,就打印所传的参数
print(word)
say()
say('哈全')
# def mysql(host,user,passwd,post=3306):#如果有些参数是必填的,有些参数是默认的,那么必填参数必须写到默认值参数前面
def op_fille(fillname,count=None):
with open('fillname','a+',encoding='utf-8') as fw:
fw.seek(0)
if count:
fw.write(count)
else:
res=fw.read()
return res
op_fille('a.txt','cc')
#需求分析:
#1、判断小数点个数是否为1
#2、按照小数点分隔,取到小数点左边和右边的值
#3、判断正小数,小数点左边为整数,小数点右边为整数
#4、判断负小数,小数点左边以负号开头,并且只有一个负号,负号后面为整数,小数点右边为整数
def is_float(s):
s=str(s)
if s.count('.')==1:
left,right = s.split('.')
if left.isdigit() and right.isdigit():
print('正小数')
return True
elif left.startswith('-')and left.count('-')==1 and left[1:].isdigit() and right.isdigit():
print('负小数')
return True
print('不合法')
return False
is_float(1)
is_float(0)
is_float(0.5)
is_float(-3.5)
is_float('-s.5')
is_float('-99.5')
is_float('--969.5')
is_float('--9s9.5')
is_float(--9.6)
局部变量和全局变量
局部变量意思就是在局部生效的,出了这个变量的作用域,这个变量就失效了
全局变量的意思就是在整个程序里面都生效的,在程序最前面定义的都是全局变量,全局变量如果要在函数中修改的话,需要加global关键字声明,如果是list、字典和集合的话,则不需要加global关键字,直接就可以修改。
#在函数里面定义的变量叫局部变量,只能在函数里面用,出了函数就不能用,全局变量,在整个程序里面都生效的,在程序最前面定义的
name='掌上电脑'#全局变量:如果是字符串、int、float、元组就需要声明global
stus=[]#如果定义的全局变量是List、字典、集合不用声明
def a():
# global name#声明global,就会修改全局变量的值
name='哈哈哈'#局部变量#同一个变量在函数外面有在函数里面有,先在函数里面找,如果能找到变量就输出函数里面的变量,如果找不到就去函数外面找,输出函数外面的变量
stus.append('abc')
print(name)
def b():
age=18
print(name)
print('stus是:',stus)
a()
b()
#练习
money=500
def test(consume):
return money-consume
def test1(money):
return test(money)+money
money=test1(money)
print(money)
def test():
global a
a=5
def test1():
c=a+5#没有调用全局变量
return c
test()#调用函数
res=test1()
print(res)
浅拷贝和深拷贝
浅拷贝:
两个变量指向的是同一块内存地址
深拷贝:
是会开辟一个新的内存,存放数据,就是两块不同内存。
li=[1,1,2,3,4,5,6,7,8,9]
#根据下标来取,第一次循环的时候会把下标为1的删除,第二次循环的时候,下标为0的已经取过了就不会再取了,就会跳过一个
for i in li:
if i%2 !=0:
li.remove(i)
print(li)
#上面这个结果是:[1, 2, 4, 6, 8]这个结果是有问题的
#不可以循环删除List,会导致结果错乱
#解决:再定义一个相同的list,循环一个List但是 删除另外一个list
import copy
li=[1,1,2,3,4,5,6,7,8,9]
# li1=[1,1,2,3,4,5,6,7,8,9]
# li1=li#不能直接li1=li,原因:两个都是取的同一个内存地址(浅拷贝:一个内存地址)
# li1=li[:]
li1= copy.deepcopy(li)#深拷贝:两个内存地址
#怎么看内存地址:如下
print(id(li))
print(id(li1))
for i in li1:
if i%2 !=0:
li.remove(i)
print(li)
位置参数:
位置参数,字面意思也就是按照参数的位置来进行传参,比如说上面的calc函数,x和y就是位置参数,位置参数是必传的,
有几个位置参数在调用的时候就要传几个,否则就会报错了,那如果有多个位置参数的话,记不住哪个位置传哪个了怎么办,可以使用位置参数的名字来指定调用
比如说上面的那个calc函数也可以使用calc(y=1,x=2)这样来调用,这种调用方式叫做关键字传参
PORT=3306#变量名都是大写,这种是常量,代表这个值不会变
#关键字传参:
def mysql(host,user,password,port,charset,sql,db):
print('链接mysql')
#指定参数传参
mysql(user='root',password='123',host='192.163.1.102',port='3306',sql='dffff',db='dddd',charset='sdfw')#不用按照顺序
mysql('192.168.1.102','root',port='3306')#可以前面按照传参顺序不指定关键字,后面指定关键字传参
# mysql(password='123','root')#不能先指定关键字传参,后面不指定传参(位置传参),这样后面的不指定就不知道传给谁
#位置传参
mysql('root','123','192.163.1.102','3306','dffff','dddd','sdfw')
非固定参数:
上面的两种位置参数和默认参数都是参数个数是固定的,如果说我一个函数,参数不是固定的,我也不知道以后这个函数会扩展成啥样,可能参数越来越多,这个时候如果再用固定的参数,那后面程序就不好扩展了,这时候就可以用非固定参数了,非固定参数有两种,一种是可变参数,一种是关键字参数。
可变参数:
可变参数用*来接收,后面想传多少个参数就传多少个,如果位置参数、默认值参数、可变参数一起使用的的话,可变参数必须在位置参数和默认值参数后面。可变参数也是非必传的。
def mysql2(*info):
print(info)
mysql2('ip','user',123450,000000,'sdfwer','dsfsda')
mysql2()
mysql2(1)
mysql2(1,2)
#这种参数是非必传的
#没有限制传参的个数
def send_email(*email):#在元组里面取值的时候
print(email)
#用在参数比较多的时候
def send_email(name,*email):#name是必填参数
print(email)
# 如果是下面这种传参就不可以用固定参数了
# def send_email(*email)
# send_email(email='')
#参数类型
#1、必填参数、位置参数
#2、默认值参数,非必传
#3、可变参数、非必传,不限制个数
def calc(a,b):
print(a+b)
return a+b
l=[1,2]
calc(*l)#这种传参:*会把l解成两个变量传给a,b
#上面这种位置参数和list要一致,不一致就会报错
#习惯性大家是这样定义的:
def send_email(*args):#在元组里面取值的时候,不限制参数的个数
print(args)
关键字参数:
关键字参数使用**来接收,后面的参数也是不固定的,想写多少个写多少个,当然也可以和上面的几种一起来使用,如果要一起使用的话,关键字参数必须在最后面。
使用关键字参数的话,调用的时候必须使用关键字传参。关键字参数也是非必传的。
1
2
3
|
def kw_arg(name,**kwargs):#位置参数、关键字参数,调用的时候会把传入的关键字参数放到kwargs这个字典中
print(name,kwargs)
kw_arg('sriba',sex='男',age=18)#调用,sex和age就是关键字调用
|
def mysql(**mysql_info):
print(mysql_info)
mysql()#参数放到元组里,参数不必填
# mysql('ip','user')#这种方式不能传参,因为这 种传参方式是放在一个字典里,这样就不知道哪个是key,哪个是values
mysql(ip='192.168.101.2',port=3306)#可以用,参数放到元组里
def request(url,method,**info):
print(url)
print(method)
print(info)
if info.get('data'):
data=info.get('data')
elif info.get('file'):
file=info.get('file')
request('api.nnzhhp.cn','get',data='name=aa&age=18',header='sdfdsfdsfdfa=adada',file='xxxx/a.txt')
#一般习惯性的写kwargs:
def request(url,method,**kwargs):
print(url)
print(method)
print(kwargs)
if kwargs.get('data'):
data=kwargs.get('data')
elif kwargs.get('file'):
file=kwargs.get('file')
request('api.nnzhhp.cn','get',data='name=aa&age=18',header='sdfdsfdsfdfa=adada',file='xxxx/a.txt')
#关键字参数:非必传,不限制个数,会把传过来的关键字参数放到不念旧恶字典里面,传参的时候必须用k=v这可以来传
def mysql(host,user,password,port,charset,sql,db):
print('链接mysql')
print(host)
dic={
'host':'192.168.1.102',
'user':'root',
'password':123456,
'port':9980,
'charset':'utf-8',
'sql':'sql',
'db':'db'
}
mysql(**dic)#会把字典拆开传到函数里,但字典里面的key必须和函数里面的变量一致
常用模块
#常用模块:一个python文件就是一个模块
#模块分为三种:
#标准模块:python自带的
#第三方模块,需要安装的
#自己写的Python文件
#标准模块:
import json
#json模块是用来解析json的
#josn就是个字符串
#定义一个json串:#josn串必须用双引号
#字典不能写到文件里面,文件里面只能写字符串
# json_str='''
# {"name":"xiaohei","age":18,"sex":"男"}
# '''
# res=json.loads(json_str)#把josn转成字典
# print(res)
# print(type(res))
# print(type(json_str))
dic={"name":"xiaohei","age":18,"sex":"男"}
res=json.dumps(dic,ensure_ascii=False)#把字典变成一个字符串
print(res)
print(type(dic))
print(type(res))
f=open('user.txt','w',encoding='utf-8')#把字典写到文件里面变成josn串
f.write(res)
#多次嵌套字典
dic1={
"小黑":{
"age":18,
"addr":"深圳",
"sex":"男",
"password":1234
},
"小红": {
"age": 18,
"addr": "深圳",
"sex": "男",
"password": 1234
},
"小草": {
"age": 18,
"addr": "深圳",
"sex": "男",
"password": 1234
}
}
#dumps方法一:
# res1=json.dumps(dic1,ensure_ascii=False,indent=4)#ensure_ascii显示中文,indent缩进
# print(res1)
# g=open('user.json','w',encoding='utf-8')
# g.write(res1)
#dump方法一:自己写,操作文件
fw=open('newuser.json','w',encoding='utf-8')
re3=json.dump(dic1,fw,ensure_ascii=False,indent=4)
print(re3)
#在线校验Josn:www.bejosn.com
# f2=open('user.json',encoding='utf-8')
# res2=json.loads(f2.read())#这种需要自己读
# print(res2)
#python里面字典打印出来的都是单引号,如果是json打印出来的都是双引号
f2=open('user.json',encoding='utf-8')
res2=json.load(f2)#从文件里面来就直接读出来
print(res2)
time模块:
import time
#格式化好的时间
#时间戳:
print(time.time())
#五天后的时间
print(time.time()+86400*5)
#精确到秒
print(int(time.time()+86400*5))
#取当前格式化好的时间
res=time.strftime('%Y-%m-%d %H:%M:%S')
print(res)
#想格式化好的时间转成时间戳,时间戳想转化好格式化好的时间都得先转成时间元组
#时间戳转成时间元组,时间戳转格式化好的时间
res1=time.gmtime(8565895000)
print(res1)
res2=time.strftime('%Y-%m-%d %H:%M:%S',res1)#strftime如果后面传了时间元组,就会把时间元组按格式转化,如果没传时间元组默认取当前时间
print(res2)
time1=time.gmtime(int(time.time()))#取当时日期,时间+8,默认以标准时区的时间转换的
print(time1)
time2=time.strftime('%Y-%m-%d %H:%M:%S',time1)
print(time2)
locatime1=time.localtime(int(time.time()))#locatime取当前位置的时间
print(locatime1)
locatime2=time.strftime('%Y-%m-%d %H:%M:%S',locatime1)
print(locatime2)
#格式化好的时间转时间戳
rwa=time.strptime('2018-12-08 13:47:57','%Y-%m-%d %H:%M:%S')
print(rwa)
rwa1=time.mktime(rwa)#把时间元组转时间戳
print(rwa1)
# time.sleep(90)#停多少秒
def timestampToStr(timestamp=None,format='%Y-%m-%d %H:%M:%S'):
#传了时间,时间戳转格式化好的时间
if timestamp:
locatime1 = time.localtime(timestamp)
res=time.strftime(format,locatime1)
#没传时间,返回当当前时间
else:
res=time.strftime(format)
return res
res2=timestampToStr(52658974)
print(res2)
def strTotimestamp(str=None,format='%Y%m%d%H%M%S'):
#格式化好的时间转时间戳
if str:
rwa = time.strptime(str,format)
rwa1 = time.mktime(rwa)
else:
rwa1=time.time()
return int(rwa1)
res3=strTotimestamp('20181208140854')
print(res3)
os模块:
import os
res=os.listdir('C:\Alimama')#列出某个目录下的所有文件
print(res)
# 输出所有文件和文件夹
for file in res:
print(file)
# os.remove()#方法用于删除指定路径的文件。如果指定的路径是一个目录,将抛出OSError。
# os.rename()#os.rename() 方法用于命名文件或目录,从 src 到 dst,如果dst是一个存在的目录, 将抛出OSError。
# # os.mkdir(r'test/niuhy/haha')#创建文件夹
# path = 'C:/Alimama/home1'
# os.mkdir( path)#创建文件夹
# os.makedirs(r'test1/lyl/aaa')#会创建父目录
# os.makedirs() 方法用于递归创建目录。
# path = "C:/Ali/home2"
# os.makedirs( path)
#os.path.exists() 方法来检测文件是否存在:
path="C:/Ali/home2/新建文本文档.txt"
res = os.path.exists(path)#os.path.exists() 方法来检测文件是否存在:
print(res)
# os.path.isfile() #判断是否为文件
path="C:/Ali/home2/新建文本文档.txt"
res1 = os.path.isfile(path)#os.path.exists() 方法来检测文件是否存在:
print(res1)
# os.path.isdir()#判断是否为文件夹
path="C:/Ali/home2"
res2 = os.path.isdir(path)#os.path.exists() 方法来检测文件是否存在:
print(res2)
print( os.path.split('C:/Ali/home2/新建文本文档.txt') )# 分割文件名与路径
# res = os.path.split(r'/Users/nhy/Desktop/stu.txt')
print( os.path.dirname('C:/Ali/home2/新建文本文档.txt') ) # 返回目录路径
res = os.path.dirname(r'/Users/nhy/Desktop/stu.txt')#取父目录
#os.getcwd() 方法用于返回当前工作目录。
res3 = os.getcwd() #获取当前的目录
print(res3)
#os.chdir() 方法用于改变当前工作目录到指定的路径。
# 修改当前工作目录
path="C:/Ali/home2"
res4=os.chdir( path )
print(res4)
# os.chdir(r'/Users/nhy/Desktop/')#更改当前目录
print(os.environ)#看你电脑的环境变量
res5 = os.path.join('test','hhh','abc','a.txt')#拼接路径
print(res5)
res6= os.path.abspath('..')#根据相对路径取绝对路径
file='/root/runoob.txt' # 文件路径
print( os.path.abspath(file) ) # 输出绝对路径
print(res6)
res7 = os.system('hhhsdf')#执行操作系统命令
os.system('mkdir today') # 执行系统命令 mkdir
print(res7)
res8 = os.popen('gg').read()
print('res8',res8)
练习
1、写一个程序,输入N就产生N条双色球号码
红球 6 01-33
蓝球 1 01-16
产生的双色球号码不能重复,写到一个文件里面,每一行是一条
红球: 01 03 05 07 08 18 蓝球:16
红球需要排序,是升序
import random
#方法一:
# def qui(num):
# num=int(num)
# ssq=set()
# while len(ssq) !=num:
# read_ball = random.sample(range(1, 34), 6)
# read_ball.sort()
# bull_ball = random.randint(1, 16)
# read_ball.append(bull_ball)
# print(read_ball)
# s = ''
# for i in read_ball:
# i = '%02d' % i
# s = s + i + ' '
# ssq.add(s + '\n')
# with open('cc','a',encoding='utf-8') as fw:
# fw.writelines(ssq)
#方法二:#列表生成式
# def ssq(num):
# num=int(num)
# squi=set()
# while len(squi) !=num:
# read_ball=random.sample(range(1,34),6)
# read_ball.sort()
# blue_ball=random.randint(1,16)
# read_ball.append(blue_ball)
# all_ball=[str(ball).zfill(2) for ball in read_ball]
# res=' '.join(all_ball)
# squi.add(res+'\n')
# with open('bb','w',encoding='utf-8') as fr:
# fr.writelines(squi)
# return squi
# num=input('请输入一个数')
# write=ssq(num)
# print(write)
#方法三:定义两个函数
# def red_ball(num):
# num=int(num)
# res_set=set()
# while len(res_set) !=num:
# read_ball=random.randint(1,33)
# readball='%02d'%read_ball
# res_set.add(readball)
# res_set1=list(res_set)
# res_set1.sort()
# redball=' '.join(res_set1)
# return redball
# # red_ball(1)
# def allball(count):
# count=int(count)
# all_ball=set()
# while len(all_ball) !=count:
# star_ball=red_ball(6)
# end_ball=random.randint(1,16)
# seq='红球:%s,蓝球:%02d\n'%(star_ball,end_ball)
# all_ball.add(seq)
# with open('aa','w',encoding='utf-8') as fd:
# fd.writelines(all_ball)
# return all_ball
#
# count=input('请输入一个数')
# write1=allball(count)
# print(write1)
2、写一个商品管理的程序:
1、添加商品
商品名称:商品已经存在的话,要提示
商品价格: 校验,是大于0的数字
商品数量:校验,只能是大于0的整数
2、删除商品
商品名称:商品不存在的话,要提示
3、查看商品
显示所有的商品信息
4、退出
#添加
#商品名称
#添加不存在的商品(从文件里面读出Key,看商品是否存在,存在就不能添加)
#价格
#价格只能是大于0的整数或正小数(判断价格是否合理)
#数量
#数量,只能是大于0的整数
#把原来的文件变成字典,在字典里面添加商品:
# product={
# "爱疯差":{
# "price":99.8,
# "count":10
# }
# }
# product['name']={"price":100,"count":1}
#写字典重新全部写到文件里面
# write(product)
#删除
#读文件,判断商品是否存在,存在才能删除,不存在不能删除
# product={
# "爱疯差":{
# "price":99.8,
# "count":10
# }
# }
# product.pop('爱疯差')
#把剩下的商品全部写到文件里面
# write(product)
#查询
# 读文件,判断文件是否存在,存在才能查
#添加,删除,查询共同方法:读文件里面的商品
#添加,删除共同方法;重新商品字典写入文件
#因为文件名不会变,所以把文件名定义成一个常量(全部大写来定义说明它是一个常量)
FILENAME='product.json'
#获取文件
import json
def get_product():
with open('FILENAME','a+',encoding='utf-8') as fr:
fr.seek(0)
counte=fr.read()
if counte:
res=json.loads(counte)
else:
res={}
return res
#把添加的东西写到文件里面
def write_product(product_dict):
with open('FILENAME','w',encoding='utf-8') as fw:
json.dump(product_dict,fw,ensure_ascii=False,indent=4)
#判断价格是否合理
def is_price(s):
s=str(s)
if s.count('.')==1:
left,right=s.split('.')
if left.isdigit() and right.isdigit():
return float(s)
elif s.isdigit():
if int(s)>0:
return int(s)
else:
return False
#判断数量是否合法
def counted(s):
if s.isdigit() and int(s)>0:
return int(s)
#添加商品:
def add():
allproduct=get_product()
name=input('请输入商品名称').strip()
price=input('请输入商品价格').strip()
count=input('请输入商品数量').strip()
if not name or not price or not count:
print('商品名称或价格或数量不能为空')
elif name in allproduct:
print('商品已经存在')
elif not is_price(price):
print('输入的价格不合法')
elif not counted(count):
print('数量不合法')
else:
allproduct[name] = {"price1": float(price), "count1": int(count)}
write_product(allproduct)
print('添加成功')
#删除商品
def delete():
allproduct = get_product()
name = input('请输入商品名称').strip()
if not name:
print('商品名称不能为空')
elif name not in allproduct:
print('商品不存在')
else:
allproduct.pop(name)
write_product(allproduct)
print('删除成功')
#查看商品
def show():
allproduct = get_product()
name = input('请输入商品名称').strip()
if not name:
print('商品名称不能为空')
elif name not in allproduct:
print('商品不存在')
else:
print(allproduct)
choice = ['添加商品','删除商品','显示商品','退出']
for index,a in enumerate(choice):
print('%s ===>%s'%(index+1,a))
res = input('请输入对应的编号进入对应的操作:')
if res=="1":
add()
elif res=="2":
delete()
elif res=="3":
show()
elif res=="4":
quit('程序退出')
else:
print('输入有误')
#函数名不可以与变量叫同样的名字#下面的a函数不能再被调用了
def a():
print('a)
a=23
#函数即变量
def a():
print('adfddfd')
b=a
b()
choice = input('1、add\n'
'2、delete\n'
'3、show \n'
'4、exit \n')
function_map={"1":add,"2":delete,"3":show,"4":exit}
if choice in function_map:
function_map[choice]()
else:
print('输入有误')