pthon总结
-
- 1、python 3种基本数据类型
- 2、python 字典
- 3、python 列表
- 4、python 集合
- 5、python 字符串
- 6、python 元组
- 7、python 运算符(成员、比较、算术、赋值、身份、逻辑)
-
- 7.1、成员运算符
- 7.2、比较运算符
- 7.3、算术运算符
- 7.4、身份运算符
- 7.5、逻辑运算符
- 8、python 逻辑控制
-
- 8.1、if
- 8.2、for
- 8.3、while
- 8.4、循环跳出和冒牌排序
- 9、python 函数的多个参数和多个返回值
-
- 10、python 匿名函数
- 11、python 变量链式赋值和作用域
-
- 12、python 面向对象-基本用法
- 13、python 面向对象-封装
- 14、python 面向对象-抽象类
- 15、python 面向对象-特殊属性类方法静态方法
- 16、python 面向对象-继承
- 17、python 面向对象-面向对象的组合用法
- 18、python 面向对象-面向对象的组合用法
- 19、python 列表、字典推导式
- 20、python 解包列表、元组、字典
- 21、python 提前申明变量类型
- 22、python 字典、列表、字符串类型转化
- 23、python 把浏览器headers直接复制使用
- 24、python @contextmanager上下文
- 25、python args和kwargs
- 26、python 异常(手动抛出、自定义)
- 27、jsonpath(精准、模糊、过滤)
- 28、定时器
1、python 3种基本数据类型
'''使用python3.6以上版本才有数据类型定义 '''
import math
i:int=1
f:float=1.22
s:str='字符串'
print(f'{i,f,s}')
'''int和float转化'''
print(float(i))
print(round(3.526,2))
print(math.floor(3.526))
print(math.ceil(3.526))
print(math.modf(3.526))
'''数字类型和str'''
print(int('12'))
print(float('12.1'))
2、python 字典
dict1 = {'key': 'value'}
d = dict(name='Bob', age=20, score=88)
print(dict1)
print(dict1['key'])
dict1['cc'] = 22
dict1['cc'] = 33
del dict1['cc']
dict1.clear()
print(dict1)
dict1.update({1: 1, 2: 2})
dict1.update({1: 1.0, 3: 3})
print(dict1)
print(dict1.pop(2))
print(dict1)
dict2 = {1: 1, 2: 2}
for k, v in dict2.items():
print(k, v)
if 'kk' not in d:
print('kk不在字典d中')
d.update({'kk': 99})
if d.pop('kk') == 99:
print('kk被新增了,但是又被我干掉了')
3、python 列表
list1 = [1, "2", "进阶"]
print(list1)
list2 = [1, "2", "进阶", [1, 2]]
print(list2)
list3 = ['c', 'a', 'd', 'g']
print(list3[1])
print(list3[1:2])
list4 = ['c+'] + ['+']
print(list4)
list5 = ['2', '1', 2, 4, "dd"]
print(list5 * 3)
list5.append(1)
print(list5)
list5.insert(1, 'xl')
list5.pop()
list5.pop(0)
print(list5)
print(list5.index(2))
print(list5.count(1))
print(list5)
list5.reverse()
print(list5)
print(list5[::-1])
'''写个方法 校验列表是否有相同的元素'''
def chan(l):
for i in l:
if l.count(i)>1:
return i
4、python 集合
'''
集合:
无序,没有索引
不支持数据重复
'''
set1 = {1, 2, 3, 4, 1, "5"}
print(set1)
print({1, 2, 3, 4, 5} - {1, 2})
print({1, 2, 3, 4, 5} & {1, 2})
print(({1, 2, 3, 4, 5} | {3, 5, 6, 7}))
print(type(set()))
print(type({}))
5、python 字符串
str1 = '1jaskj'
'''
字符串[开始索引:结束索引:步长]
切取字符串为开始索引到结束索引-1内的字符串(取头不取尾)
步长不指定时步长为1 字符串[开始索引:结束索引]
'''
print(str1[0])
print(str1[-1])
print(str1[1:3])
print(str1[::-1])
a='a\a\a\a'
b=r'a\a\a\a'
6、python 元组
tuple1 = (1, "2", "进阶")
print(tuple1)
tuple2 = (1, "2", "进阶", (1, 2))
print(tuple2)
tuple3 = ('c', 'a', 'd', 'g')
print(tuple3[1])
print(tuple3[1:2])
print(tuple3[1:3])
print((1))
print((1,))
'''神奇'''
a = {1: 1},
print(type(a))
b = [1, 2],
print(type(b))
7、python 运算符(成员、比较、算术、赋值、身份、逻辑)
7.1、成员运算符
print(1 in[1,'2m'])
print(1 not in[1,'2m'])
print('c' in {'c':1})
print(1 in {'c':1})
7.2、比较运算符
print(1 == 1)
print(1 >= 1)
print(1 <= 1)
print(1 > 1)
print(1 < 1)
print(1 != 1)
b = 1
b += b >= 1
print(b>=1)
print(int(True))
print(b)
7.3、算术运算符
print(1 + 1)
print(1 - 1)
print(1 * 1)
print(4 / 2)
print(7 % 2)
print(2 ** 2)
print(2 ** 5)
7.4、身份运算符
'''
总结:
对象的三个特征 id value type
只有三个特征都相等时 使用 is 的结果才为True
而使用==时只需要value的结果就是True
'''
print(1 is 1)
print(1 is not 2)
print('1' is 1)
print(1 is 1.0)
print(1 == 1.0)
print(1 == True)
print(1 is True)
a = {1, 2, 3}
print(id(a))
b = {1, 3, 2}
print(id(b))
print(a == b)
print(a is b)
print(type(1) == int)
print(isinstance(1, int))
print(isinstance("2", str))
print(isinstance(1, (int, str, float)))
print(isinstance({1: 1}, (int, str, float)))
7.5、逻辑运算符
print(True and True)
print(False and True)
print(False and False)
print(True or True)
print(False or True)
print(False or False)
8、python 逻辑控制
8.1、if
'''
非0和非空(null)值为true,0 或者 null为false。
'''
if 0:
print('0为false')
if None:
print('表达式为None')
if 1:
print('非0为true')
if '1':
print('表达式为非空')
a=3
if a==1:
print('a=1')
elif a==2:
print('a=2')
else:
print('a==0')
a=2
print(a)
8.2、for
'''几次常规用法'''
for i in range(1,4):
print(i)
for i in range(4):
print(i)
a=[1,2,3,'ll','24']
for i in a:
print(i)
b={'k1':'v1','k2':'v2','k3':'v3'}
for i in b.keys():
print(i)
for i in b.values():
print(i)
for k,v in b.items():
print(k,v)
8.3、while
import random
a=1
while a<3:
print('进来时a={}'.format(a))
a+=1
print('出去时a={}'.format(a))
print('循环运行完的a={}'.format(a))
count=0
while a<=7:
count+=1
a+=random.randint(2,9)
else:
print('a运行了{}次就大于7了,a={}'.format(count,a))
8.4、循环跳出和冒牌排序
'''
break是直接结束当前循环
continue是结束当前循环的剩余语句进行下一论的循环
continue 语句是一个删除的效果,他的存在是为了删除满足循环条件下的某些不需要的成分
'''
for i in 'py1thon':
if i == '1':
break
print(i)
print('-------------------------------------')
for i in 'py1thon':
if i == '1':
continue
print(i)
print('-------------------------------------')
a = [2, 1, 4, 6, 2, 3, 5, 9, 7]
for i in range(len(a)-1):
for j in range(len(a)-1):
if a[j] >= a[j + 1]:
a[j],a[j+1]=a[j+1],a[j]
9、python 函数的多个参数和多个返回值
9.1、多个参数
'''
默认参数:
它是如何工作的
名为 func 的函数有一个没有默认参数值的参数,后跟两个各自带有默认参数值的参数。
在第一次调用python函数时,func(3, 7),参数 a 获得了值 3,参数 b 获得了值 7,而 c 获得了默认参数值 10。
在第二次调用函数时,func(25, c=24),由于其所处的位置,变量 a 首先获得了值 25。然后,由于命名——即关键字参数——指定,变量 c 获得了值 24。变量 b 获得默认参数值 5。
在第三次调用函数时,func(c=50, a=100),我们全部使用关键字参数来指定值。在这里要注意到,尽管 a 在 c 之前定义,但我们还是在变量 a 之前指定了变量 c。
'''
def sum(a, b=1):
return a + b
print(sum(1))
def func(a, b=5, c=10):
print(a, b, c)
func(3, 7)
func(25, c=24)
func(c=50, a=100)
def t(a,*b,c=2):
print(a)
print(b)
print(c)
t(1,2,1,c=5)
'''
结果
1
(2, 1)
5
'''
9.2、多个返回值
def aa():
a=1
b=2
return {'a':a,'b':b}
a=aa()
print(type(a))
def bb():
c=2
d=4
return c,d
'''还可以这样访问使用函数返回的2个参数'''
c,d=bb()
print(c,d)
10、python 匿名函数
'''lambda 匿名函数用法 add和add1 实现的是一样的功能'''
def add(x, y):
return x+ y
print(add(3,4))
add1 = lambda x,y:x+y
print(add1(3,4))
ge=lambda a : [int(a),str(a)]
l=ge(1)
print(l)
11、python 变量链式赋值和作用域
11.1、链式赋值
d=1,2,3
print(d)
'''a,b=[1,2,2] 需要一一对应,不管是1,2,3,[1,2,3],(1,2,3)都需要一一对应'''
a,b,c=1,2,3
print(a,b,c)
a,b,c=[1,2,3]
print(a,b,c)
print(type(a))
a,b,c=(1,2,3)
print(a,b,c)
print(type(a))
a=b=c=1
print(a,b,c)
c=2
print(a,b,c)
11.2、作用域
'''要调用这个方法后才能使用这个函数里面的局部变量,感觉不好用'''
def text():
global add
add= "http://c.biancheng.net/java/"
print("函数体内访问:",add)
text()
print('函数体外访问:',add)
12、python 面向对象-基本用法
class Person:
role = 'person'
def __init__(self, name, attack, hp):
self.name = name
self.attack = attack
self.hp = hp
def hit(self, dog):
dog.hp -= self.attack
class Dog:
role = 'dog'
def __init__(self, name, breed, attack, hp):
self.name = name
self.breed = breed
self.attack = attack
self.hp = hp
def bite(self, person):
person.hp -= self.attack
xiao_wang = Person('小王', 10, 1000)
re_ha = Dog('二哈', '哈士奇', 3, 500)
print('小王的血条={}'.format(xiao_wang.hp))
print('二哈的血条={}'.format(re_ha.hp))
'''小王连续踢了三下狗'''
for i in range(3):
xiao_wang.hit(re_ha)
'''二哈咬了一下小王'''
re_ha.bite(xiao_wang)
print('小王的血条={}'.format(xiao_wang.hp))
print('二哈的血条={}'.format(re_ha.hp))
13、python 面向对象-封装
class A:
'''私有属性和方法只能在类内部使用'''
__x = 1
y = 2
def __gai_y(self):
self.y += 1
def du_y(self):
print('y的值为{}'.format(self.y))
def test(self):
self.__gai_y()
print(self.__x)
class B(A):
'''继承的类不能使用父类的私有属性和方法'''
__b='b'
bb='bb'
def b1(self):
print(self.__b)
b=B()
b.b1()
14、python 面向对象-抽象类
'''从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法'''
import abc
class All_file(metaclass=abc.ABCMeta):
all_type='file'
@abc.abstractmethod
def read(self):
'子类必须定义读功能'
pass
@abc.abstractmethod
def write(self):
'子类必须定义写功能'
pass
class Txt(All_file):
def read(self):
print('txt文本数据的读取方法')
def write(self):
print('txt文本数据的写入方法')
class Execl(All_file):
def read(self):
print('execl文本数据的读取方法')
def write(self):
print('execl文本数据的写入方法')
15、python 面向对象-特殊属性类方法静态方法
from math import pi
class G:
'''@property 直接把方法的返回值当作一个属性值,存储在属性名为当前方法名的属性里面,可以通过对象.之间访问'''
def __init__(self,r):
self.r=r
@property
def area(self):
return self.r**2*pi
g=G(2)
print(g.area)
class Method:
'''类方法可以之间类来调用,而实例方法需要用对象来调用'''
a=1
@classmethod
def test_cls(cls):
print('类方法里使用变量a={}'.format(cls.a))
def test_self(self):
print('实例方法里面使用变量a={}'.format(self.a))
@staticmethod
def ha():
'''静态方法里面无法使用self,也无法使用类里面的属性值和方法,只是一个普通的方法挂在这个类下面方便查找'''
print('打印日志')
me=Method()
me.test_cls()
me.test_self()
Method.test_cls()
Method.ha()
16、python 面向对象-继承
class A:
a=1
def __init__(self,aa,aaa):
self.aa=aa
self.aaa=aaa
def ay(self):
print('A')
class B(A):
'''B继承A,B的对象可以调用A和B的属性和方法'''
def by(self):
print('B')
class C(A):
'''继承父类的构造方法,2种写法,如果继承多个类就不要用super()这种方法了'''
def __init__(self,aa,aaa,bb):
super().__init__(aa,aaa)
self.bb=bb
def cy(self):
print('C')
class D(A):
'''重写父类方法,方法名相同,如果想使用父类被重新的方法,可以使用super().ay()或者A.ay(self)使用'''
def dy(self):
print('D')
def ay(self):
print('重新父类方法A-D')
def ay_A(self):
A.ay(self)
super().ay()
17、python 面向对象-面向对象的组合用法
'''一个类的属性是另外一个类的对象'''
class Skill:
def Q(self):
print('哈撒k')
def W(self):
print('风墙')
def E(self):
print('踏前斩')
def R(self):
print('狂风觉息斩')
class Hero:
def __init__(self, name):
self.name = name
self.skill = Skill()
'''需求:亚索放技能
2Q,EQ双风W接R
'''
ya_sou = Hero('亚索')
ya_sou.skill.Q()
ya_sou.skill.Q()
ya_sou.skill.E()
ya_sou.skill.Q()
ya_sou.skill.W()
ya_sou.skill.R()
'''
圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用
'''
from math import pi
class Circle:
def __init__(self, r):
self.r = r
def perimeter(self):
return 2 * pi * self.r
def area(self):
return pi * self.r * self.r
class CircularRing:
def __init__(self, inside_r, outer_r):
self.inside_track = Circle(inside_r)
self.outer_ring = Circle(outer_r)
def perimeter(self):
return self.inside_track.perimeter() + self.outer_ring.perimeter()
def area(self):
return self.outer_ring.area() - self.inside_track.area()
cr = CircularRing(3, 5)
print(cr.perimeter())
print(cr.area())
18、python 面向对象-面向对象的组合用法
'''一个类的属性是另外一个类的对象'''
class Skill:
def Q(self):
print('哈撒k')
def W(self):
print('风墙')
def E(self):
print('踏前斩')
def R(self):
print('狂风觉息斩')
class Hero:
def __init__(self, name):
self.name = name
self.skill = Skill()
'''需求:亚索放技能
2Q,EQ双风W接R
'''
ya_sou = Hero('亚索')
ya_sou.skill.Q()
ya_sou.skill.Q()
ya_sou.skill.E()
ya_sou.skill.Q()
ya_sou.skill.W()
ya_sou.skill.R()
'''
圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用
'''
from math import pi
class Circle:
def __init__(self, r):
self.r = r
def perimeter(self):
return 2 * pi * self.r
def area(self):
return pi * self.r * self.r
class CircularRing:
def __init__(self, inside_r, outer_r):
self.inside_track = Circle(inside_r)
self.outer_ring = Circle(outer_r)
def perimeter(self):
return self.inside_track.perimeter() + self.outer_ring.perimeter()
def area(self):
return self.outer_ring.area() - self.inside_track.area()
cr = CircularRing(3, 5)
print(cr.perimeter())
print(cr.area())
19、python 列表、字典推导式
import random
print([i for i in 'dadasd'])
a = ['1', 2, 'kk', 4, 0]
b = [i for i in a if isinstance(i, int)]
print(b)
d1 = {'one': 1, 'two': 2, 'three': 3, 1: 1}
d2 = {i for i in d1}
print(d2)
d3 = {k: v for k, v in d1.items() if v > 1}
print(d3)
d4 = {v: k for k, v in d1.items()}
print(d4)
d5 = {'li{}'.format(i): random.randint(60, 100) for i in range(20)}
d6 = {k: v for k, v in d5.items() if v >= 90}
print(d6)
d7 = [i for i in d6]
print(d7)
d8 = [i for i in range(1, 101) if i % 2 == 0 and i>=60]
print(d8)
20、python 解包列表、元组、字典
'''*解包 把 oo拆成3个值'''
oo=(1,2,3)
ll=[2,4,6]
def uu(a,b,c):
print(a,b,c)
uu(*oo)
uu(*ll)
'''**解包 拆解字典解字典为这样的格式 a=1,b=2,c=3,*拆解字典的话只能得到键的值'''
dd={'a':1,'b':2,'c':3}
uu(*dd)
uu(**dd)
'''解包合并字典和列表'''
list1=[1,2,3]
list2=[4,5,6]
print([*list1,*list2])
dict1={1:1,2:2}
dict2={3:3,4:4}
print({**dict1,**dict2})
21、python 提前申明变量类型
'''变量注解 更多详情参考https://www.dusaiphoto.com/article/164/ 建议python3.9使用再去参考,现在先就用这些'''
age = 20
print(type(age))
age = '20'
print(type(age))
b:int =1
b='2'
print(b)
a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False
'''函数注解 定义函数的返回类型'''
def st(s:str) -> str:
return s+'字符串'
print(st('1'))
def hello(p: 'Person') -> str:
return f'Hello, {p.name}'
class Person:
def __init__(self, name: str):
self.name = name
p=Person('kk')
print(hello(p))
22、python 字典、列表、字符串类型转化
'''列表 和 字符串'''
import random
list1 = [1, '2', 3, 'kk']
print(str(list1))
'''
join()方法 是以字符串里面的内容分割每个列表的元素,然后变为字符串
需要注意的是该方法需要list中的元素为字符型,若是整型,则需要先转换为字符型后再转为str类型
'''
s = "".join([str(i) for i in list1])
print(s)
str1 = 'klo10'
l = list(str1)
print(l)
'''字典 和 字符串'''
d1 = {1: 1, 2: 2}
d2 = str(d1)
print('d2的值{},类型为{}'.format(d2, type(d2)))
'''把d2要重新转化为字典格式直接用dict(d2)是会报错的'''
d3 = eval(d2)
print('d3的值{},类型为{}'.format(d3, type(d3)))
'''eval()函数 可以字符里面写表达式储存起来,再用eval()函数使用赋值给变量'''
random_str = "'测试{}'.format(random.randint(100,99999))"
print(eval(random_str))
'''列表 和 字典'''
list1 = ['1', '2', '3']
list2 = [1, 2, 3, 1]
print('相同长度的列表(多余的会自动干掉)转换为字典(哪个列表在前面就是键){}'.format(dict(zip(list2, list1))))
'''写个方法,当列表长度不一样是可以自动补充键值'''
def l_d(l1, l2):
dict2 = {}
if len(l1) == len(l2):
for i in range(len(l1)):
dict2[l1[i]] = l2[i]
return dict2
elif len(l1) > len(l2):
for i in range(len(l1)):
if i >= len(l2):
dict2[l1[i]] = None
else:
dict2[l1[i]] = l2[i]
return dict2
else:
k = 0
for i in range(len(l2)):
k += 1
if i >= len(l1):
dict2['k{}'.format(k)] = l2[i]
else:
dict2[l1[i]] = l2[i]
return dict2
print(l_d(list1, list2))
dict0 = {'ll': 2, 'cc': 0, 'dd': '1'}
'''键转为列表'''
print([i for i in dict0.keys()])
'''值转为列表'''
print([i for i in dict0.values()])
23、python 把浏览器headers直接复制使用
from copyheaders import headers_raw_to_dict
x=b'''
{
"hasThird":false,
"thirdCarrierName":"",
"thirdCarrierNo":true,
"thirdPlatForm":null,
"thirdContractNo":"",
"thirdContractName":"",
"shiftWaybillDTOList":[
{
"waybillId":xxx
}
]
}
'''
r=headers_raw_to_dict(x)
print(r)
print(type(r))
24、python @contextmanager上下文
from contextlib import contextmanager
@contextmanager
def book_mark():
print('《', end='')
yield
print('》', end='')
with book_mark():
print("年少不努力", end='')
@contextmanager
def file_open(file_name):
try:
yield
except FileNotFoundError as e:
print(file_name)
file_name = 'data1.txt'
with file_open(file_name):
open(file_name, mode='r')
25、python args和kwargs
'''
不能将**kwargs置于*args前,否则将产生错误;
“args kwargs ”是一个标准化规范 使用其他的名称也是可以的 *args 和 *没有区别 kwargs也是
最好使用标准规范
'''
'''传参查看参数'''
def a(b, *c):
print(f'b={b}---c={c}')
a(1, (1, 2, 3, 4))
a(1, 2, 3, 4, 5)
a({1:1})
def b(b, **c):
print(f'b={b}---c={c}')
b(1, d=1, c=1)
'''使用'''
def lis(*args):
print(f'args={args},类型为{type(args)}')
lis(1,2,3)
a=[1,3,'d']
b=(1,3,'d')
lis(a)
lis(b)
def dic(**kwargs):
print(f'kwargs={kwargs},类型为{type(kwargs)}')
dic(d=1,c=2)
26、python 异常(手动抛出、自定义)
a=[1,2,3]
try:
print(a[4])
except ZeroDivisionError:
print('被除数为0异常')
except IndexError as e:
print(f'索引异常。异常信息:{e}')
except Exception:
print('没有发现上述异常,未知异常')
else:
print('没有异常')
finally:
print('有无异常我都执行')
x=2
if x>2:
raise Exception('x不能大于2')
class NameLengthError(Exception):
'''当名字长度大于5位时抛出该异常'''
def __init__(self,length :int):
self.length=length
def __str__(self):
if self.length>5:
return f'姓名的长度最大为5位,您输入的位数为{self.length}位'
return ''
length=3
try:
raise NameLengthError(length)
except NameLengthError as e:
print(e)
27、jsonpath(精准、模糊、过滤)
import jsonpath
d = {
"error_code": 0,
"stu_info": [
{
"id": 2059,
"name": "亚索",
"sex": "男",
"age": 28,
"addr": "德玛西亚",
"grade": "天蝎座",
"info": {
"card": 434345432,
"bank_name": '中国银行',
'name': 'dddd'
}
},
{
"id": 2067,
"name": "李青",
"sex": "男",
"age": 28,
"addr": "虾子岛",
"grade": "天蝎座",
}
]
}
print(jsonpath.jsonpath(d, '$.stu_info.1.id'))
print(jsonpath.jsonpath(d, '$.name'))
print(jsonpath.jsonpath(d, '$..name'))
print(jsonpath.jsonpath(d, '$...card'))
a = [1, 2, [3, 4, [5, 6]]]
print(jsonpath.jsonpath(a, '$.2.2.0'))
c = {'code': 200,
'data': [
{'create_time': '2016-01-29 13:49:13',
'link': 'http://www.ehoutai.com/', 'uid': 7, 'name': '易后台'},
{'create_time': '2016-01-29 13:42:15',
'link': 'http://www.sanjieke.com/', 'uid': 4, 'name': '三节课'},
{'create_time': '2016-01-29 13:40:53',
'link': 'https://www.aliyun.com/', 'uid': 1, 'name': '阿里云'},
{'create_time': '2016-01-29 14:01:59',
'link': 'http://xmanlegal.com/', 'uid': 8, 'name': '未来法律'}]}
print(jsonpath.jsonpath(c, '$.data[?(@.uid==4)]'))
print(jsonpath.jsonpath(c, '$.data[?(@.uid==4)][name]'))
print(jsonpath.jsonpath(c, '$.data[?(@.uid>4)]'))
print(jsonpath.jsonpath(c,'$.data[?("xm" in @.link)]'))
28、定时器
import threading
import time
def run():
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
timer = threading.Timer(2, run)
timer.start()
run()