python
1. python的基础
- python是动态语言、强类型定义的,解释型语言。
- 动态和静态语言的区别:动态语言不用指定数据类型,而静态语言需要指定。
- 强类型定义语言:一个变量指定了某个类型,如果不经过强制转换,就永远是这个类型。弱类型定义语言:一个变量可以复制不同数据类型。
- python的优点:有很多库,开发效率高,可移植,可扩展和可嵌入。
- 现在一般使用的是CPYTHON,pypy是python的解释器,采用JIT(即时编译),加快python的速度。
- python目前是3.6版本
- 3.0和2.0最大的改变,是可以写中文了,print必须要加括号
2. 变量和常量
1. 变量的规则 数字、字母、下划线,数字不能开头
2. name = “Partrick Zh”
name2 = name
print (“My name is” ,name,name2) 结果:两个Partrick Zh
name = “kimy cui”
print (name,name2) 结果:kimy cui ,Partrick Zh
name 变了,但是name2没有变,name2不是指向name,而是指向的name的值,所以当name改变的时候,name2指向的还是原先name的值。
3. 常量的命名规则是 NAME = “123” 一般常量都是大写,与变量区分。
4. 上述字母不能用于变量,因为在python中已被定义过。
3. 字符编码
1. ASCII 255个,为西方国家设计的,每个英文1bytes
-->1980 gb2312 7000多个汉字
-->1995 GBK1.0 2W+
-->2000 GB18030 2W7
--> unicode 英文中文统一都2bytes 国际统一编码标准
--> utf-8是unicode压缩版 英文:1bytes 中文:3bytes
2. python2默认支持ASCII 不支持UTF-8如果要在python2里面使用中文必须在要声明
# -*- coding:utf-8 -*-
python3.5.2默认支持utf-8
4. 注释
1. '''
name = "你好,世界"
print (name)
'''
三个单引号代表注释一段,如果在前面加上变量str = ‘’’ sdflsdjfklsd‘’’ 单引号里面的内容就变成了一个字符串。
#号代表注释当前行
5. 用户输入
1. name = input("name") 输入的方式 相当于shell 的read -p
age = input("age")
info = '''
------------- info of %s 注:%s代表占位符
Name: %s
Age: %s
''' % (name,name,age)
print (info)
2. name = input("name")
age = int( input("age")) 把string类型转换成int类型
print (type (age)) 打印age的类型,默认是string
info = '''
------------- info of %s
Name: %s
Age: %d 代表整数
''' % (name,name,age)
print (info)
注:python2里面不要用input,用raw_input相当于python3里面的input
3.用format来赋值输出
info2 = '''
------------- info of {_name}
Name: {_name}
Age: {_age}
''' .format(_name=name,
_age=age)
print (info2)
4.用{}的方式来赋值(一般情况下不用)
info3 = '''
------------- info of {0}
Name: {0}
Age: {1}
''' .format( name,age)
print (info3)
6. 密文输入if else
import getpass 定义一个密文输入的源
age_oldboy = int(input("age_oldboy"))
guess_age_oldboy = getpass.getpass("guess_age_oldboy")
print(guess_age_oldboy)
if age_oldboy == guess_age_oldboy:
print("yes ,you got
it".format(age_oldboy))
elif age_oldboy > guess_age_oldboy:
print("think
smaller".format(guess_age_oldboy))
else:
print("think
bigger".format(guess_age_oldboy))
注:if需要顶头写,print前面需要缩进
7. while循环
# Author:Zhang
#import getpass
age_oldboy = '31'
count = 0
while True:
if count==3:
break
guess_age_oldboy =
input("guess_age_oldboy:")
if age_oldboy == guess_age_oldboy:
print("yes ,you got
it".format(age_oldboy))
break
elif age_oldboy > guess_age_oldboy:
print("think smaller".format(guess_age_oldboy))
else:
print("think
bigger".format(guess_age_oldboy))
count +=1
优化while
# Author:Zhang
#import getpass
age_oldboy = '31'
count = 0
while count <3:
guess_age_oldboy = input("guess_age_oldboy:")
if age_oldboy
== guess_age_oldboy:
print("yes ,you got it".format(age_oldboy))
break
elif age_oldboy > guess_age_oldboy:
print("think smaller".format(guess_age_oldboy))
else:
print("think bigger".format(guess_age_oldboy))
count +=1 注:必须写在else里面,并且和else对齐
else: 注:这里的else和while对齐
print("fuck off")
8. for循环
for i in
range(4,10,3):
print ("loop",i)
age_oldboy = '31'
count = 0
while count <3:
guess_age_oldboy =
input("guess_age_oldboy:")
if age_oldboy == guess_age_oldboy:
print("yes ,you got
it".format(age_oldboy))
break
elif age_oldboy >
guess_age_oldboy:
print("think
smaller".format(guess_age_oldboy))
else:
print("think
bigger".format(guess_age_oldboy))
count +=1
if count==3:
countinue_confirm =
input("do you want to keep guessing")
if countinue_confirm !='n':
count=0
9. continue
for i in range(0,10):
if i<3:
print("loop",i)
else :
continue
print("hehe...")
注:如果i<3打印hehe 如果i>=3,就跳出这个循环不打印hehe,continue是跳出这个循环,break是结束这个循环。
10. for循环嵌套
for i in range(0,10):
print('-----------')
for j in range(0,10):
print(j)
if j>5:
break
11. 函数sys和os
import sys
print(sys.path) 打印路径
本地库的路径C:\Python35\lib
第三方库 C:\Python35\lib\site-packages
print(sys.argv[0]) 打印当前脚本所在的路径
import os
cmd=os.system("dir")
print("---->",cmd) 打印目录在屏幕上,0代表成功
cmd=os.popen("dir").read() 打印目录并保存
print("---->",cmd)
os.mkdir("new_dir2") 新建目录
12. 函数的调用
函数调用可以通过import 函数名
被调用的那个函数需要放在site-packages(第三方库里面)
13. 简述Python的运行过程
- PycodeObject和Pyc文件
- python和java一样虽然是解释型语言但是也是先编译的,编译成pycode,当python运行的时候,编译结果是保存在内存的pycode中,当python运行结束后,python解释器将pycode写回到pyc文件中。
- 当python二次执行的时候,会先找pyc文件,如果没有再继续前面的过程。
- pyc里面存储的是个预编译后的字节码文件,不是机器码。
14. 数据类型
1 数字 int
- 浮点 float
- 负数 4+11j
- 布尔值 真或假 分别代表1或0
15. encode和decode
encode是编码 decode是解码
print(msg.encode(encoding="utf-8"))
print(msg.encode(encoding="utf-8").decode(encoding="utf-8"))
16. 数据的增删该查
names=["1zhanghao","#lipengcui","3zhangyanxi","4zhouchunxiu"]
#names.append("shiyue") 追加到结尾
names.insert(2,"shiyue") 增加
names[2]="dsb"
del names[2] 删除
#print(names[1:4])
names.reverse() 反转
names.sort() 排序(按ASII码顺序)
print(names[:4])
print(names[-5:])
#print(names.index("zhanghao"))
print(names.append("zhanghao"))
#print(names.count("zhanghao"))
names2=[1,2,3,4]
names.extend(names2) 合并
del names2
print(names)
17. 深copy和浅copy
person=[“name”,[“a”,100]]
p1=copy.copy(person) 浅copy
p2=person[:] 相当于person[-1:1]
p3=list(person) 浅copy
p1[0]=’zhanghao’
p2[0]=’lipengcui’
p1[1][1]=50
print(p1)
print(p2)
浅copy可以用联合账号
copy.deepcopy(names) 深copy 复制前后没有变化
18. 元组
- names=('zhanghao','xx')
只有两个方法一个是count和index
作用是只能查不能修改,因为没有方法
19. 程序练习
需求:
1. 启动程序后,让用户输入工资,然后打印商品列表
- 允许用户根据商品编号购买商品
- 用户选择商品后,检查余额是否够,够就直接扣款,不够就提醒
- 可随时退出,退出时,打印已购买商品和余额
# Author:Zhang
#print(salary)
shopping = [('IPhone',5800),
('Mac Pro',12000),
('Starbuck Latte',31),
('zhanghao book',81),
('Bike',800)
]
shopping_list=[]
salary=input("please input your salary :")
if salary.isdigit():
salary = int(salary)
else:
print("invide input")
exit()
while True:
#for index,item in
enumerate(shopping):
#print(index,item)
for i in shopping:
print(shopping.index(i),i)
user_choice=input("选择商品>>>:")
if user_choice.isdigit():
user_choice=int(user_choice)
if user_choice<len(shopping)
and user_choice >=0:
p_item=shopping[user_choice]
if p_item[1] <=salary:
shopping_list.append(p_item)
salary-= p_item[1]
print("Add %s
into shopping cart,your current balance is 33[31;1m%s 33[0m"
%(p_item,salary))
else:
print(" 33[41;1m你的余额只剩[%s]啦,还买个毛线 33[0m"%(salary))
else:
print("product code
[%s] is not exist!"% user_choice)
elif user_choice=='q':
print('-----------shopping
list-----------')
for p in shopping_list:
print(p)
print("Your current
balance:",salary)
exit()
else:
print("invalid
option")
20.字符串函数的应用
1. name = 'my name is
patrick'
print(name.capitalize())
My name is patrick 首字母大写
2. print(name.count("a")) 统计字符的个数
3. print(name.center(50,'-')) 一共打印50个字符,不够用-补全,并放在中间
----------------my name is patrick----------------
4 print(name.endswith('ck'))以什么结尾,如果是,就返回true
- name = 'my name is patrick'
print(name.expandtabs(tabsize=30))
my name is patrick
将 转换成多少个空格
- print(name[name.find("name"):9])用于字符串切片,将name切分出来
- name = 'my name is {name} and i am {year} old'
print(name.format(name='patrick',year='30'))
my name is patrick and i am 30 old 赋值
8. print('abc123'.isalnum()) 如果是英文+数字就返回true
- print('abcACB'.isalpha())如果是英文(大小写)就返回true
10.print('12AB'.isdecimal())如果是10进制返回true
11 print('aA'.isidentifier())判断是否是合法的变量名 字母 _ 中文开头的
12 print('aa'.islower()) 判断是否是小写 返回true
13 print('Aa'.istitle())是否是titile,首字母大写返回true
14 print('MY'.isupper())是否是大写字母,返回true
15 print('+'.join( ['1','2','3','4'] )) 后面是字符串
1+2+3+4
16 print(name.ljust(50,'#'))50个字符,不够的在右边用#进行补全
17 print(name.ljust(50,'#'))
18 print('patrick'.upper()) 小写变成大写
19 print('PATRICK'.lower())大写变成小写
20 print(' patrick'.lstrip())从左边去掉空格和回车
21 print('patrick '.rstrip())从右边去掉空格和回车
22 print(' patrick '.strip())从两边去掉空格和回车
23 p = str.maketrans("abcdepick",'123456789')
print("patrick".translate(p))
将abcdepick 对应后面的1234.. 然后打印patrick的时候,就对应后面的数字,有点像古时候的加密。
24 print('patrick'.replace('p','P')) 替换,将p换成P
print('patrickp'.rfind('p')) 找到最右边的p进行返回所以结果是7
25 print('pa tra icak'.split()) 可以按空格分成列表
['pa', 'tra', 'icak']
26 print('1+2+3+4'.split('+'))按照+号分成字符串
['1', '2', '3', '4']
27 print('patrick'.endswith('k')) 以什么结尾,如果是k,就返回true
print('patrick'.startswith('p'))
28.print('Patrick zhang'.swapcase())小写变成大写,大写变成小写
21. 字典操作
1. 字典是无序的,没有下标,通过key来查找
2. 字典的增删改查
info = {
'stu1101' : "Patrick
Zhang",
'stu1102' : "Aimy Li",
'stu1103' : "Xx Zhang",
} 增加
bb = {
'stu1101' : "Alex",
1:3,
2:4,
}
print(info["stu1101"]) 查询
print(info.get("stu1103")) 查找,有就显示,没有就显示NONE不会报错
info["stu1101"]="张皓" 修改
info["stu1104"]="周春秀"
del info["stu1104"] 删除
info.pop("stu1101")
print(info)
print('stu1103' in info) 取值加判断
Hao Zhang
True
info.update(bb) 把info和bb两个字典合并,有一样的就替换,没有一样的就都显示出来
print(info)
print(info.items()) 把一个字典转成一个大的列表
c = dict.fromkeys([6,7,8],[1,{"name":"patrick"},2]) 建立一个字典
c[7][1]['name']="Patrick" 如果修改字典当中的值,其他的值都会变
print(c)
{8: [1, {'name': 'Patrick'}, 2], 6: [1, {'name': 'Patrick'}, 2], 7: [1, {'name': 'Patrick'}, 2]}
for i in info:
print(i,info[i]) 循环打印字典
或者 使用
for k,v in info.items(): 先通过info.items转换成列表,然后再打印(效率特别低,)
print(k,v)
22. 三级菜单程序练习
data= {
'北京':{
"昌平":{
"沙河":["oldboy","test"],
"天通苑":["链家地产","我爱我家"],
},
"朝阳":{
"望京":["奔驰","陌陌"],
"国贸":{"CICC","HP"},
"东直门":{"Advent","飞信"},
},
"海淀":{
"北京四中":["CCCC","DDDD"],
},
},
'山东':{
"德州":{},
"青岛":{},
"济南":{},
},
'广东':{
"东莞":{},
"常熟":{},
"佛山":{},
},
}
exit_flag = False
while not exit_flag:
for i in data:
print(i)
choice = input("选择进入1>>:")
if choice
in data:
while not exit_flag:
for i2 in data[choice]:
print(" ",i2)
choice2 = input("选择进入2>>:")
if choice2
in data[choice]:
while not exit_flag:
for i3 in data[choice][choice2]:
print(" ", i3)
choice3 = input("选择进入3>>:")
if choice3 in data[choice][choice2]:
for i4 in data[choice][choice2][choice3]:
print(" ",i4)
choice4 = input("最后一层,按b返回>>:")
if choice4 == "b":
pass
elif choice4 =="q":
exit_flag = True
if choice3 == "b":
break
elif choice3 == "q":
exit_flag = True
if choice2 == "b":
break
elif choice2 == "q":
exit_flag = True
23. 集合
1. 定义一个集合
list_2 = set([2,6,0,66,22,8,4])
2. 集合的交集、并集、子集、差级、对称差级
print(list_1.difference(list_2)) 交集
或者print(list_1 & list_2)
print(list_1.union(list_2)) 并集
或者print(list_1 | list_2)
print(list_1 - list_2) 差集
print(list_3.issubset(list_1)) 子集
print(list_1.issuperset(list_3)) 父集
print(list_1.symmetric_difference(list_2)) 对称子集
或者print(list_1 ^ list_2)
3. 集合的添加删除
list_1.add(999) 添加
list_1.update([888,777,666])
print(list_1.pop()) 删除
list_1.discard(888)
24.读取文件、写文件、追加文件
f = open("yesterday2",'r',encoding="utf-8") #文件句柄
#data = f.read()
#print(data)
f = open("yesterday2",'w',encoding="utf-8") #文件句柄
f.write("我爱李鹏毳,
")
f.write("我更爱我老妈和老爸")
f = open("yesterday2",'a',encoding="utf-8") #文件句柄
f.write("我爱李鹏毳.....
")
f.write("我更爱我老妈和老爸......")
f.close()
注释:写文件的时候会自动创建一个yesterday2,是一个空文件,会自动覆盖
追加文件会自动在文件的尾部追加,不会覆盖。
25. 读取指定多行文件、readlines、readline
f = open("yesterday",'r',encoding="utf-8")
for i in range(5)
print(f.readline())
指定第3行插入一个“我是分割线”
low loop
for index,line in
enumerate(f.readlines()):
if index ==3:
print('-----我是分割线----')
continue
print(line.strip())
注:写入内存中,如果是20个G,特别慢,一行一行的读
high bige
count=0
for line in f:
if count
== 3:
print('-----我是分割线----')
count +=1
continue
print(line.strip()) --》取出空格
count +=1
注:读取一行、删除一行,效率很高。
26. 文件的读写、写读、追加读写
print(f.tell()) 读取字符串的下标
print(f.readline()) 读取一行
print(f.readline())
print(f.tell())
f.seek(0)
移动下标到哪里
print(f.readline())
print(f.tell())
print(f.encoding) 打印字符编码
print(f.flush()) 刷新将字符串写入文件(硬盘)
print(f.readline())
f.seek(2)
f.truncate(5)
如果是写的话,会覆盖,如果是追加的实话会从第5个开始
f = open("yesterday2",'r+',encoding="utf-8") #读写(写入的内容追加到最后一行)
f = open("yesterday2",'w+',encoding="utf-8") #写读
f = open("yesterday2",'a+',encoding="utf-8") #追加读写
f = open("yesterday2",'rb')#文件句柄 二进制文件 读
f = open("yesterday2",'wb')#文件句柄 二进制文件 写
f = open("yesterday2",'ab')#文件句柄 二进制文件 追加
进度条
import sys,time
for i in range(20):
sys.stdout.write("#")
sys.stdout.flush() 刷新到屏幕上
time.sleep(0.1) 每个0.1秒打印
27. 替换文件中的内容
f = open("yesterday2","r",encoding="utf-8")
f_new = open("yesterday2.bak","w",encoding="utf-8")
for line in f:
if "aa"
in line:
如果这样里面存在aa
line=line.replace("aa","lipengcui") 替换
f_new.write(line)
f.close()
f_new.close()
注:读源文件,写在一个新文件,在新文件中替换,不改变源文件
28. with语句
with open("yesterday2","r",encoding="utf-8") as f:
for line in f:
print(line)
注:可以打开多个文件,并且自动关闭,不用f.close()
同时打开多个文件,最好用下面的书写格式
with open("yesterday2","r",encoding="utf-8") as f ,
open("yesterday2","r",encoding="utf-8") as f2:
29. 编码解码
在python2里面
- #-*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) ASII
s="您好" utf-8
print(s)
s_to_unicode = s.decode("utf-8") utf8转换成unicode
print(s_to_unicode)
s_to_gbk=s_to_unicode.encode("gbk") unicode转换成gbk
print(s_to_gbk)
gbk_to_utf8=s_to_gbk.decode("gbk").encode("utf-8") gbk转成unicode转成utf8
print(gbk_to_utf8)
s=u"您好" 前面加个u就代表unicode
print(s)
- python文件编码是gbk,但是python里面的字符串编码是unicode
#-*- coding:gbk -*-
import sys
# Author:Zhang
s = "二哈"
print(sys.getdefaultencoding())
print(s.encode("gbk"))
print(s.encode("gbk").decode("gbk").encode("utf-8"))
print(s.encode("utf-8").decode("utf-8"))
30. 函数与函数式编程
- 面向对象 class
- 面向过程 def
- 函数式编程是没有返回值的面向过程 def
# Author:Zhang
#函数
def func1():
"""testing1"""
print('in the func1')
return 0
#过程
def func2():
'''testing2'''
print('in the func2')
x=func1()
y=func2()
print('from
func1 return is %s'%x)
print('from
func2 return is %s'%y)
31. 使用函数的优点
- 使用函数的优点:代码重用、保持一致性、可扩展性
- # Author:Zhang
import time
def logger():
time_format = '%Y-%m-%d %X'
time_current = time.strftime(time_format)
with open('a.txt','a+') as f:
f.write('%s and i ove mm '%time_current)
def test1():
print('in the test1')
logger()
def test2():
print('in the test2')
logger()
def test3():
print('in the test3')
logger()
test1()
test2()
test3()
32. 函数返回值
def test1():
print('in the test1') 返回空
def test2():
print('in the test2')
return 0 返回0
def test3():
print("in the test3")
#return 1,'hello',['alex','zhanghao'],{'name':'alex'} 返回一个元祖
return test2 返回<function test2 at
0x000000000070E268> 这个是test2函数的路径
x=test1()
y=test2()
z=test3()
print(x)
print(y)
print(z)
33. 函数传参 关键参数、位置参数、默认参数
# Author:Zhang
def test(x,y,z):
print(x)
print(y)
print(z)
#test(1,2) #与形参一一对应
test(y=1,x=2,z=3) #与形参顺序无关
test(3,z=2,y=4)
注:关键参数是不能写在位置参数前面的 x=2是关键参数 (2,3)是位置参数,当同时存在关键参数和位置参数的时候,关键参数写前面,位置参数可以互换
默认参数
def test(x,y=2):
print(x)
print(y)
test(1)
#默认参数特点:调用函数的时候,默认参数非必须传递
#用途:1.默认安装值
参数组*args和**kwargs
#def test1(x,*args):
#print(x)
#print(args)
#test1(1,2,3,4,5,6,7) 只能接收位置参数,不能接收关键字参数,转换成元祖的形式
#test1(*[1,2,3,4,5])
#def test2(**kwargs): 把N个关键字参数转换成字典
#print(kwargs['name'])
# print(kwargs['age'])
# print(kwargs['sex'])
#test2(name='alex',age=8,sex='F')
#test2(**{'name':'alex','age':8})
'''def test3(name,**kwargs):
print(name)
print(kwargs)
test3('patrick',age=18,sex='m')
'''
#def test4(name,age=18,**kwargs):
#print(name)
#print(age)
#print(kwargs)
#test4('alex',sex='m',hobby='tesla',age=3)
def test5(name,age=18,*args,**kwargs):
print(name)
print(age)
print(args)
print(kwargs)
test5('alex',age=34,sex='m',hobby='tesla')
34. 局部变量和全局变量
# Author:Zhang
school = "Oldboy edu."
#全局变量
def change_name(name): #局部变量只在函数里生效,这个函数就是这个变量的作用域
global school #在函数里面定义全局变量,可以改变定义在外面的那个全局变量
school = "Mage Linux"
print("before change",name,school)
name="Alex li"
print("after change",name)
name = "alex"
change_name(name)
print(name,school)
如果全局变量是字典或者字符串,局部变量可以修改
names = ['alex','jack']
def aa():
names[0] = 'zhanghao'
print(names)
aa()
print(names)
35. 递归函数
递归函数:在函数内部,可以调用其他函数,如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归特性:1. 必须要有一个明确的条件
2 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3 递归效率不高,递归层次过多会导致栈溢出。
def calc(n):
print(n)
if int(n/2)>0:
return calc(int(n/2))
print("->",n)
calc(10)
36. 函数编程、高阶函数
- 函数编程:只要输入是确定的,输出就是确定的。
- 高阶函数:变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def add(a,b,f):
return f(a)+f(b)
res=add(3,-6,abs)
print(res)
注:abs是一个绝对值函数。
- 3. 如何把字符串变成字典
b={aa:bb,cc:dd}
通过eval(b)就可以把字符串转成字典
b='''{
'bakend': 'www.oldboy.org',
'record':{
'server':'100.10.2.3',
'weight':20,
'maxconn':30
}
}'''
b=eval(b)
print(b['record'])
37. 装饰器
- 定义:本质是函数,(装饰其他函数):就是为其他函数添加附加函数。
- 原则:1. 不能修改被装饰函数的函数的源代码。
2 不能修改被装饰的函数的调用方式。
3. 实现装饰器知识储备
- 函数即“变量”。
- 高阶函数
a: 把一个函数名当做实参传递给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)。
b: 返回值中包含函数名。(不修改函数的调用方式)
(a)import time
def bar():
time.sleep(3)
print('in the bar')
def test1(func):
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
test1(bar)
(b) import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func
bar=test2(bar)
bar()
- 嵌套函数
def foo():
print('in the foo')
def bar():
print('in the bar')
bar()
foo()
装饰器脚本1
import time
def timer(func): #timer(test1) func=test1
def deco():
start_time=time.time()
func() #
run test1()
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
return deco
@timer #test1=timer(test1)
def test1():
time.sleep(3)
print('in the test1')
装饰器脚本2(加参数)
import time
def timer(func): #timer(test1) func=test1
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs) #
run test1()
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
return deco
@timer #test1=timer(test1)
def test1():
time.sleep(3)
print('in the test1')
@timer #test2=timer(test2)
def test2(name,age):
print('in the test2:',name,age)
test1() #--->deco
test2("patrick","30")
装饰器脚本3(判断密码正确是否登陆)
import time
user,passwd='patrick','123'
def auth(func):
def wrapper(*args,
**kwargs):
username = input("Username:").strip()
password = input("Password:").strip()
if user
== username and passwd == password:
print("