python学习小记

 

多版本环境配置

一般下载python并安装即可在命令行中使用python,不需要进行其他配置。

多版本的情形:若多个python项目对同一个依赖包要求的版本不同,甚至不同项目要求的python版本不同,则要用到python的多版本管理能力。

解决:在同一台机器上同时开发多个项目时,通常是为每个项目分别创建python环境而不是使用安装在OS的python环境,以在各自环境下安装依赖包,从而减少可能的互相干扰。有 venv、pyenv 两种途径达到该目的。

venv 是 python 自带的模块,可通过  python -m venv $dir_name && cd $dir_name && ./bin/pip install -r $project/requirements.txt  创建一个 venv 环境、在该环境内安装项目的依赖包,然后在该 venv 下执行  ./bin/activate  启用该环境(每次登录都要手动启用,除非加到启动脚本例如 ~/.bashrc 中)

pyenv 是一个程序,用于在同一个OS安装并管理不同版本的 python ,需要单独下载安装(见:https://github.com/pyenv/pyenv-installer)。两大功能:

管理不同版本 python :可通过  pyenv install $version  命令安装不同版本 python 。

管理 venv : pyenv virtualenv $YourVenvName && pyenv activate $YourVenvName && pip install -r $project/requirements.txt  ,背后实际上就是以当前版本的 python 创建 venv 并将依赖安装到该 venv 中,与上面 venv 的效果等价。

通过 pyenv 创建 venv 时可能会由于OS上同时有2.7、3.5+ 版本且默认 python 版本为2.7而报小于3.5的错,需要将默认版本改为3.5以上。如果真的去改可能会遇到很多阻力,怎么解决?直接通过 python3 创建个 3.5+ 的 venv、接着激活该venv、然后再执行pyenv的上述功能。这有点鸡生蛋蛋生鸡的感觉。

可见,pyenv 比 venv 功能更强大,因此更推荐用 pyenv 。缺点是需要单独另外安装。

 

 

一行代码启动Python自带的http server:

# python 2
python -m SimpleHTTPServer 端口号 
# python 3
python -m http.server 端口号

 

 

python HTTP请求示例:

  1 # coding=utf-8
  2 
  3 # more materials: http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
  4 
  5 import requests
  6 import json
  7 import time
  8 
  9 import pymysql
 10 
 11 myhost = "http://127.0.0.1:8080"
 12 myurl = ""
 13 mytoken = ""
 14 myheaders = {}
 15 myparams = {}
 16 mybodydata = {}
 17 
 18 
 19 
 20 def test1():
 21     # POST demo
 22     print "\n POST demo"
 23     myurl = myhost + "/api/v1/auth/login"
 24     mybodydata = {"username": "杜甫", "password": "123"}
 25     r = requests.post(myurl, data=json.dumps(mybodydata))
 26     # print r.text
 27     mytoken = r.json()["token"]
 28     print mytoken
 29 
 30     # GET demo
 31     print "\n GET demo"
 32     myurl = myhost + "/api/v1/student/experiment"
 33     myheaders = {"X-Authorization": "Bearer "+mytoken}
 34     myparams = {
 35         "studentId": "664e8106-0552-45e9-8518-5fab535fe036", "chapter": 2}
 36     r = requests.get(myurl, headers=myheaders, params=myparams)
 37     # print r.text
 38     print r.json()[0]["studentId"]
 39 
 40     # PUT demo
 41     print "\n PUT demo"
 42     myurl = myhost + "/api/v1/student/experiment/completion"
 43     myheaders = {"X-Authorization": "Bearer "+mytoken}
 44     myparams = {"studentId": "664e8106-0552-45e9-8518-5fab535fe036", "experimentId": "2.1",
 45                 "modifyTimestamp": "2018-11-21 11:10:11",  "finishedSteps": 3}
 46     r = requests.put(myurl, headers=myheaders, params=myparams)
 47     # print r.text
 48     # print r.json()["studentId"]
 49     return
 50 # test1()
 51 
 52 
 53 def test2(i, postfix):
 54     # POST demo
 55     print "\n POST demo"
 56     myurl = myhost + "/api/v1/admin/student"
 57     myheaders = {'content-type': 'application/json', "X-Authorization": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLnrqHnkIblkZgiLCJzY29wZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VySWQiOiJhZG1pbjAwMDEiLCJpc3MiOiJ6aHV5YW5ibyIsImlhdCI6MTUyODMzODkzMCwiZXhwIjoxNTMxOTM4OTMwfQ.psAqK4nl5eE9DkD14c3TMYXaMkp4ydDnjNagT61ja96WzBl41M3ZTL-oatMXSqvXk1ExDQkW0SCyl01HJyEiSg"}
 58     mybodydata = {"schoolId": "1", "schoolNumber": "SY1506"+postfix,
 59                   "name": name[i], "gender": "0", "grade": "高一(6)班",
 60                   "age": 18, "status": "online", "bz": bz[i],
 61                   "phone": "110", "ip": ip[i], "port": port[i]}
 62     r = requests.post(myurl, headers=myheaders, data=json.dumps(mybodydata))
 63     print r.text
 64     # mytoken=r.json()["token"]
 65     # print mytoken
 66     return
 67 # 不能有分号,fuck
 68 # test2()
 69 
 70 
 71 ip = ["10.5.31.18", "10.5.31.18", "10.5.31.18", "10.5.31.18", "10.5.31.18", "10.5.31.18", "10.5.31.18", "10.5.31.18", "10.5.31.21", "10.5.31.21", "10.5.31.21", "10.5.31.21", "10.5.31.21", "10.5.31.21", "10.5.31.21", "10.5.31.21", "10.5.31.24", "10.5.31.24", "10.5.31.24", "10.5.31.24", "10.5.31.24", "10.5.31.24", "10.5.31.24", "10.5.31.24", "10.5.31.27", "10.5.31.27", "10.5.31.27", "10.5.31.27", "10.5.31.27", "10.5.31.27", "10.5.31.27", "10.5.31.27", "10.5.31.30", "10.5.31.30", "10.5.31.30", "10.5.31.30",
 72       "10.5.31.30", "10.5.31.30", "10.5.31.30", "10.5.31.30", "10.5.31.33", "10.5.31.33", "10.5.31.33", "10.5.31.33", "10.5.31.33", "10.5.31.33", "10.5.31.33", "10.5.31.33", "10.5.31.36", "10.5.31.36", "10.5.31.36", "10.5.31.36", "10.5.31.36", "10.5.31.36", "10.5.31.36", "10.5.31.36", "10.5.31.39", "10.5.31.39", "10.5.31.39", "10.5.31.39", "10.5.31.39", "10.5.31.39", "10.5.31.39", "10.5.31.39", "10.5.31.42", "10.5.31.42", "10.5.31.42", "10.5.31.42", "10.5.31.42", "10.5.31.42", "10.5.31.42", "10.5.31.42"]
 73 port = ["5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004",
 74         "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008"]
 75 name = ["林达华", "戴娟", "周丹", "倪枫", "范青", "郑文滨", "张富华", "蔡文晖", "吴军", "王若晖", "李治中", "朱雁博", "李晓波", "吴青", "张绍铭", "杨焕州", "王睿", "陈向东", "严一滨", "周畅", "胡志洪", "朱元锟", "敖培", "冷春波", "马军", "张龙", "王英", "段斯译", "闫兴华", "黄山", "方小培", "汪义超", "王梦", "佟彤", "张秀政", "李卫平", "曾皓明",
 76         "王广科", "张振堂", "徐正一", "沈杨", "何博", "刘晓丹", "钱 晋", "王霄驰", "穆青", "朱永生", "崔懿", "朱勋", "万景华", "王美佳", "王辉", "江艳萍", "张炜其", "李守志", "刘平", "李鲋瑞", "王智荣", "于新平", "常学勤", "王明江", "章良", "姜波", "王建伟", "武绍玮", "吴时敏", "蓝滚波", "stu01", "stu02", "stu03", "stu04", "stu05"]
 77 bz = ["商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "商汤", "华东师范大学第二附属中学", "华东师范大学第二附属中学", "华东师范大学第二附属中学乐东黄流中学", "上海交通大学附属中学", "上海交通大学附属中学", "上海市晋元高级中学", "上海市晋元高级中学", "中山纪念中学", "晋城市第一中学", "山西省汾阳中学校", "深圳外国语学校", "广东广雅中学", "广东广雅中学", "合肥市第一中学", "合肥市第一中学", "中央民族大学附属中学", "哈尔滨工业大学附属中学校", "山西孝义中学", "孝义市教育局", "浙江省镇海中学", "江苏省邗江中学", "甘肃省兰州第一中学",
 78       "上海市格致中学", "上海市格致中学", "上海市格致中学", "上海市格致中学", "上海市市西中学", "上海市市西中学", "山东省青岛第二中学", "合肥市第六中学", "上海市七宝中学", "河南大学附属中学", "东北育才学校", "辽宁省实验中学", "新疆农业大学附属中学", "浙江省温岭中学", "北京市第十一中学校", "贵阳市第一中学", "深圳华侨城中学", "深圳华侨城中学", "山西省实验中学", "山西省实验中学", "未来科技", "西北师范大学附属中学", "上海光华教育集团", "郑州市第二中学", "郑州市第二中学", "郑州市第二中学", "贵阳一中金塔英才学校", "博罗县东江广雅学校", "绑定端口的学生测试账号", "绑定端口的学生测试账号", "绑定端口的学生测试账号", "绑定端口的学生测试账号", "绑定端口的学生测试账号"]
 79 
 80 for i in range(1, 73):
 81     num = "%02d" % i
 82     # test2(i-1,num)
 83 
 84 
 85 for i in range (24,25):
 86     num = "%03d" % i
 87     myhost="http://10.5.31.15:8081"
 88     myurl = myhost + "/api/v1/admin/student"
 89     myheaders = {'content-type': 'application/json', "X-Authorization": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLnrqHnkIblkZgiLCJzY29wZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VySWQiOiJhZG1pbjAwMDEiLCJpc3MiOiJ6aHV5YW5ibyIsImlhdCI6MTUyODMzODkzMCwiZXhwIjoxNTMxOTM4OTMwfQ.psAqK4nl5eE9DkD14c3TMYXaMkp4ydDnjNagT61ja96WzBl41M3ZTL-oatMXSqvXk1ExDQkW0SCyl01HJyEiSg"}
 90     mybodydata = {"schoolId": "1", "schoolNumber": "cmcc"+num,
 91                   "name": "邢孝慈", "gender": "0", "grade": "高一(6)班",
 92                   "age": 18, "status": "online", "bz": "student test account",
 93                   "phone": "110", "ip": "10.5.31.15", "port": 5000+i}
 94     # print mybodydata
 95     # r = requests.post(myurl, headers=myheaders, data=json.dumps(mybodydata))
 96     # print r.text
 97 
 98 
 99 def test3():
100     print "\n PUT demo"
101     myurl = myhost + "/api/v1/teacher/course/experiment/step"
102     myheaders = {"X-Authorization": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLlvKDogIHluIgiLCJzY29wZXMiOlsiUk9MRV9URUFDSEVSIl0sInVzZXJJZCI6InRlYWNoZXIwMDAxIiwiaXNzIjoiemh1eWFuYm8iLCJpYXQiOjE1MjgxMDExODcsImV4cCI6MTUzMTcwMTE4N30.7c7j4vCqqNoguoA6FXuTXqkIXPLdYrSf9kYl-Yurmi0gjrOwukt5eDM1bW1O_L4yz6gbo_FpPH1murvFg8-EUg"}
103     myparams = {"courseId": "1", "experimentId": "2.1",
104                 "step": 1}
105     mybodydata = "\"he<p>你好aolisfjdlasfjklis</p>he\""
106     print mybodydata
107     r = requests.put(myurl, headers=myheaders,
108                      params=myparams, data=mybodydata)
109     print r.text
110 # test3()
111 
112 
113 # 实验步骤插入
114 myurl = myhost + "/api/v1/teacher/course/experiment/step"
115 myheaders = {'content-type': 'application/json', "X-Authorization": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLnrqHnkIblkZgiLCJzY29wZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VySWQiOiJhZG1pbjAwMDEiLCJpc3MiOiJ6aHV5YW5ibyIsImlhdCI6MTUyODMzODkzMCwiZXhwIjoxNTMxOTM4OTMwfQ.psAqK4nl5eE9DkD14c3TMYXaMkp4ydDnjNagT61ja96WzBl41M3ZTL-oatMXSqvXk1ExDQkW0SCyl01HJyEiSg"}
116 for i in range (1,7):
117     tmpContent= "(请添加 实验 0-4 步骤 "+ str(i) +" 的内容描述)"
118     mybodydata = {"experimentId": "0.4", "content": tmpContent }
119     # r = requests.post(myurl, headers=myheaders, data=json.dumps(mybodydata))
120 
121 
122 def sqlTest():
123     try:
124         conn = pymysql.connect(host="127.0.0.1", db="sensestudydev", user="root", passwd="123", port=3306)
125         sql = "select * from user"
126         cur = conn.cursor()
127         cur.execute(sql)
128         rows =  cur.fetchall()
129         print rows[0]
130         # print json.dumps(json.loads(rows[0][0]), indent=4)
131     except:
132         conn.close()
133     conn.close()
134 sqlTest()
View Code

 

python json序列化

通过 json.dumps 可能的问题:dic 的 key不是基本类型导致dumps时报key类型不支持的错、被序列化的对象是或者包含自定义的class且该classs没有在 __init__中定义属性名从而导致没有 __dict__ 属性。下面的用法解决了该两个问题:

    tmp_data = convert_dict_key_to_str(data) # 解决 json.dumps 时对于dic key不能为tuple等类型的问题
    json_data = json.dumps(tmp_data, indent = 4, default = python_to_json_value) if ret_json == True else ""

    return data, json_data

def convert_dict_key_to_str(input_dict):
    if not isinstance(input_dict, dict):
        return copy.deepcopy(input_dict)
    else:
        return {str(k): convert_dict_key_to_str(v) for k, v in input_dict.items()}

def python_to_json_value(data):
    if isinstance(data, Decimal):
        return str(data)
    if isinstance(data, type({}.values())):
        return list(data)
    if not hasattr(data, '__dict__'):
        attr_list = [attr for attr in dir(data) if not attr.startswith('_')]
        attr_dict = {attr: getattr(data, attr) for attr in attr_list}
        return attr_dict
    return data.__dict__
View Code

 

时间/日期的时区转换

import datetime
import pytz

def printInfo(date_obj):
    print('日期对象:', date_obj)
    print('时区:', date_obj.tzname(),"timestamp:", date_obj.timestamp())
    # 再将 datetime 对象转换为日期字符串
    new_date_str = date_obj.strftime(format_str)
    print('日期字符串:', new_date_str)

# 定义日期字符串和格式
date_str = '2023-06-30 23:59:59'
format_str = '%Y-%m-%d %H:%M:%S'
print('原始日期字符串:', date_str)

print(1 )
# 将日期字符串转换为 datetime 对象
date_obj = datetime.datetime.strptime(date_str, format_str)
printInfo(date_obj)

#纵向转换:字面日期和时间值一样,但不是同时的(时间戳不同)
print(2 )
date_obj =  pytz.timezone('Australia/Sydney').localize(date_obj.replace(tzinfo=None))
printInfo(date_obj)
print( 3)
date_obj =  pytz.timezone('Asia/Shanghai').localize(date_obj.replace(tzinfo=None))
printInfo(date_obj)

#斜向转换:字面日期和时间值不同,但是同时的(时间戳一样)
print(4 )
date_obj = date_obj.astimezone(pytz.timezone('Australia/Sydney'))
printInfo(date_obj)
print(5 )
date_obj = date_obj.astimezone(pytz.timezone('Asia/Shanghai'))
printInfo(date_obj)

#方案 1->3->2
print(6)
open_time = 1625065200
open_time= datetime.datetime.fromtimestamp(open_time) .astimezone(pytz.timezone('Asia/Shanghai')) .strftime('%d/%m/%Y')
print(open_time)


# 以下是输出
原始日期字符串: 2023-06-30 23:59:59
1
日期对象: 2023-06-30 23:59:59
时区: None timestamp: 1688169599.0
日期字符串: 2023-06-30 23:59:59
2
日期对象: 2023-06-30 23:59:59+10:00
时区: AEST timestamp: 1688133599.0
日期字符串: 2023-06-30 23:59:59
3
日期对象: 2023-06-30 23:59:59+08:00
时区: CST timestamp: 1688140799.0
日期字符串: 2023-06-30 23:59:59
4
日期对象: 2023-07-01 01:59:59+10:00
时区: AEST timestamp: 1688140799.0
日期字符串: 2023-07-01 01:59:59
5
日期对象: 2023-06-30 23:59:59+08:00
时区: CST timestamp: 1688140799.0
日期字符串: 2023-06-30 23:59:59
6
30/06/2021
View Code

 

posted @ 2018-07-25 09:34  March On  阅读(349)  评论(0编辑  收藏  举报
top last
Welcome user from
(since 2020.6.1)