1.arrow
Arrow提供了一個合理的宋渔、人性化的方法來創(chuàng)建辜限、操作薄嫡、格式轉換的日期颗胡,時間杭措,和時間戳钾恢,幫助我們使用較少的導入和更少的代碼來處理日期和時間瘩蚪。
安裝
pip install arrow
常用方法案例:
# -*- coding: utf-8 -*-
import arrow
'''1.獲取當前時間'''
print(arrow.utcnow()) # 獲取當前utc時間
print(arrow.now()) # 獲取當前系統時間
'''2.將時間戳轉化為arrow對象 時間戳可以是int稿黍,float或者可以轉化為float的字符串'''
print(arrow.get(1556073222))
print(arrow.get('1556073222'))
print(arrow.get(1556073222.264))
print(arrow.get('1556073222.264'))
'''將字符串轉換為arrow對象 arrow.get(string[,format_string])'''
print(arrow.get('2019-04-24 10:43:30','YYYY-MM-DD HH:mm:ss'))
print(arrow.get('2019-04-24T10:00:00.000-07:00')) # 循ISO-8601的字符串不需要格式字符串參數即可轉換
print(arrow.get('June was born in December 1994', 'MMMM YYYY')) # 可以從字符串中通過格式參數搜索時間
print(arrow.get(2019, 4, 24)) # 直接創(chuàng)建arrow對象
print(arrow.Arrow(2019, 4, 24)) # 直接創(chuàng)建arrow對象
'''arrow對象屬性 datetime,timestamp,tzinfo'''
time_msg = arrow.now()
print(time_msg.datetime)
print(time_msg.timestamp) # 時間戳
print(time_msg.naive)
print(time_msg.tzinfo) # 時區(qū)
print(time_msg.hour) # 小時
print(time_msg.day) # 日期(天)
'''時間推移 a.shift(**kwargs)'''
print(time_msg.shift(days=-1)) # 前一天
print(time_msg.shift(weeks=+1)) # 一周后
print(time_msg.shift(weekday=6)) # 距離time_msg最近的一個星期日巡球,weekday從0到6代表周一到周日
'''時間替換 a.replace(**kwargs)'''
print(time_msg.replace(hour=6)) # 將小時替換為6
'''格式化輸出 a.format([format_string])'''
print(time_msg.format())
print(time_msg.format('YYYY-MM-DD HH:mm:ss ZZ'))
2. toolz
安裝
pip install toolz
案例
# -*- coding:utf-8 -*-
'''
1.純函數
(1).它不依賴于隱藏狀態(tài)酣栈,或等效的取決于它的輸入。
(2).功能評估不會引起副作用
簡而言之起便,純函數的內部工作與程序的其余部分是隔離的窖维。
'''
# 純函數
def min(x,y):
if x<y:
return x
else:
return y
# 非純函數
exponent = 2
def powers(L):
for i in range(len(L)):
L[i] = L[i]**exponent
return L
if __name__ == '__main__':
result1 = min(6,10)
data = [1,2,3]
result2 = powers(data)
print(result1)
print(result2)
# min()函數的功能很純粹铸史,在給定相同輸入參數的情況下,它的產生的結果始終是相同的判沟。
# powers()函數的輸出結果是受到全局變量exponent影響的水评,因此是不純的媚送。
'''
2.惰性迭代器
惰性迭代器僅在必要時進行評估。它們允許我們在語義上操作大量數據疗涉,同時在內存中
保留很少的數據咱扣。它們像列表一樣,但不占用空間沪铭。
'''
# 打開一個文件偏瓤,python打開這個文件厅克,但是不讀取任何一行文本,對象book就是一個惰性迭代器硕旗。
# 當我們調用next()讀取文件內容時女责,book迭代器會在文本中慢慢前進
book = open('book_of_tools.txt')
print(next(book)) # 第一行
print(next(book)) # 下一行
# 我們可以懶惰地操作惰性迭代器而不進行任何實際計算
from toolz import map
loud_book = map(str.upper,book)
print(next(loud_book)) # 第一行
print(next(loud_book)) # 下一行
# 我們經常使用懶惰來避免一次將大數據集加載到內存中鲤竹。對大型數據集的許多計算不需要一次訪問所有數據。
# 如下是計算文本中的所有字母碘橘。
from toolz import concat, frequencies
letters = frequencies(concat(loud_book))
print(letters)
'''
3.Curry
curried函數部分評估它是否沒有收到足夠的參數來計算結果
'''
from toolz import curry
@curry
def mul(x,y):
return x*y
double = mul(2,2)
print(double)
3. peewee
安裝
pip install peewee
案列
# -*- coding:utf-8 -*-
from peewee import *
'''
Peewee 是一個簡單痘拆、輕巧的 Python ORM氮墨。
簡單规揪、輕巧、富有表現力(原詞 expressive )的ORM
支持python版本 2.6+ 和 3.2+
支持數據庫包括:sqlite字支, mysql and postgresql
包含一堆實用的擴展在 playhouse 模塊中
'''
'''
1.模型定義
賓語 對應...
模型類 數據庫表
字段實例 在桌子上的列
模型實例 在數據庫表中的行
'''
db = SqliteDatabase('people.db')
# 創(chuàng)建Person模型類
class Person(Model):
name = CharField()
birthday = DateField()
class Meta:
database = db
# 創(chuàng)建Pet模型類
class Pet(Model):
owner = ForeignKeyField(Person,backref='pets')
name = CharField()
animal_type = CharField()
class Meta:
database = db
# 創(chuàng)建數據存儲標表
db.create_tables([Person,Pet])
'''
2.存儲數據
通過save()和create()方法添加和更新記錄
'''
from datetime import date
old_wang = Person(name='wangyifan', birthday=date(1994,12,15))
old_wang.save()
# 使用create()方法添加人員
old_zhao = Person.create(name='zhaoyi', birthday=date(1996,3,13))
old_liu = Person.create(name='liuxing', birthday=date(1995,2,23))
# 更新數據時堕伪,可修改模型實例后調用save()方法保存更改
old_zhao.name = 'zhaoxue'
old_zhao.save() # 保存修改
print(old_zhao.name)
# 為人員分配寵物
wang_lucky = Pet.create(owner=old_wang, name='lucky', animal_type='dog')
zhao_ww = Pet.create(owner=old_zhao, name='ww', animal_type='dog')
# 刪除寵物
zhao_ww.delete_instance()
# 將寵物分配給其他人
wang_lucky.owner = old_zhao
wang_lucky.save()
print(wang_lucky.owner.name)
'''3.數據檢索'''
# 從數據庫獲取單個記錄 select.get()
person_a = Person.select().where(Person.name == 'wangyifan').get()
print(person_a.name,"person_a.name")
person_a = Person.get(Person.name == 'wangyifan') # 簡化寫法
print(person_a.name,"person_a.name,")
# (1)記錄列表
for person in Person.select(): # 列出數據庫中的所有人
print(person.name)
dog_list = Pet.select().where(Pet.animal_type == 'dog') # 列出所有狗及其主人的名字
for dog in dog_list:
print(dog.name, dog.owner.name)
# (2)獲取wangyifan擁有的所有寵物
for pet in Pet.select().join(Person).where(Person.name == 'wangyifan'):
print(pet.name)
# (3)排序 order_by()
for pet in Pet.select().where(Pet.owner == old_wang).order_by(Pet.name): # 列出寵物按姓名排序
print(pet.name)
for person in Person.select().order_by(Person.birthday.desc()): # 列出所有人欠雌,從年輕到年長
print(person.name, person.birthday)
#(4) 組合過濾器表達式
d1995 = date(1995, 3, 1)
d1996 = date(1996, 1, 1)
# 生日小于1995大于1996 兩個日期直接可以用Person.birthday.between(d1940, d1960)
person_list = (Person.select().where((Person.birthday < d1995) | (Person.birthday > d1996)))
for person in person_list:
print(person.name, person.birthday)
# (5)聚合和預取
for person in Person.select():
print(person.name, person.pets.count(), 'pets')
'''4.數據庫'''
# 關閉連接
db.close()
# 使用現有數據庫,如已有數據庫富俄,則可以使用模型生成器pwiz自動生成peewee模型 蛙酪。
# 例如翘盖,有一個名為charles_blog的postgresql數據庫 馍驯,則可以執(zhí)行如下命令
# python -m pwiz -e postgresql charles_blog > blog_model.py
4.pymysql
安裝
pip install PyMySQL
案例
# -*- coding:utf-8 -*-
import pymysql
'''1.數據庫查詢操作'''
db = pymysql.connect("localhost","root","root","hd_20190424") # 地址,用戶名狂打,密碼混弥,數據庫名
# 使用cursor()方法創(chuàng)建一個游標對象 cursor
cursor = db.cursor()
# 使用execute()方法執(zhí)行sql語句
cursor.execute("select version()")
# 使用fetchone()方法獲取單條數據
data = cursor.fetchone()
print("database version:%s" % data)
# 關閉數據庫連接
db.close()
'''2.數據庫插入操作'''
import pymysql
# 打開數據庫連接
db = pymysql.connect("localhost","root","root","hd_20190424")
# 使用cursor()方法獲取操作游標
cursor = db.cursor()
# SQL 插入語句
sql = """INSERT INTO hd_20190424(username,age)VALUES ('wangyifan', 25)"""
try:
# 執(zhí)行sql語句
cursor.execute(sql)
# 提交到數據庫執(zhí)行
db.commit()
except:
# 如果發(fā)生錯誤則回滾
db.rollback()
# 關閉數據庫連接
db.close()
5.PyYAML
安裝
pip install pyyaml
案例
# -*- coding:utf-8 -*-
import yaml
# 加載YAML
yaml_obj = yaml.load("""- Hesperiida
- Papilionidae
- Apatelodidae
- Epiplemidae""")
print (yaml_obj)
# PyYAML允許您構造任何類型的Python對象蝗拿。
yaml_obj2 = yaml.load("""
none:[~,null]
bool:[True,False,on,off]
int:33
float:3.1415926
list:[wangyifan,1,'ddd']
dic:[name:wang,age:25]
""")
print(yaml_obj2)
# 傾倒YAML
print yaml.dump({'name': 'Silenthand Olleander', 'race': 'Human', 'traits': ['ONE_HAND', 'ONE_EYE']})
#打開并顯示yaml文件內容
import yaml
f=open('yaml_data.ini')
data=yaml.load(f)
print data,'=========data'
#將Python對象寫入yaml文件
f=open('data.yaml','w')
data={
'name': 'Silenthand Olleander',
'race': 'Human',
'traits': ['ONE_HAND', 'ONE_EYE']
}
yaml.dump(data,f)
6.* requests
安裝
pip install requests
案例
# -*- coding:utf-8 -*-
import requests
'''1.get請求'''
# 請求
r = requests.get('https://www.baidu.com')
# 傳參
params_data = {'wd':'wangyifan'}
r = requests.get('https://www.baidu.com', params=params_data)
print(r.url) # 訪問地址
print(r.text) # 獲取網頁文本 返回的是Unicode型的數據 Unicode
print(r.content) #獲取網頁文本 返回的是bytes型也就是二進制的數據惦辛。 str
# print(r.json()) # 如果獲取的是json數據的話
print(r.status_code) # 狀態(tài)
r = requests.get('https://www.baidu.com',stream=True)
print(r.raw) # 返回原始socket respons仓手,需要加參數stream=True
print(r.raw.read(10),'====')
print(r.cookies,'===')
'''2.POST請求'''
# 請求
r = requests.post('http://httpbin.org/post', data = {'key':'value'})
# 參數
data_msg = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=data_msg)
print(r.text)
print(r.cookies)
# 文件傳遞
url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)
# session
# session對象能夠幫我們跨請求保持某些參數嗽冒,也會在同一個session實例發(fā)出的所有請求之間保持cookies。
s = requests.Session() # 創(chuàng)建一個session對象
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text,'==========')
7.* PyStaticConfiguration
安裝
# -*- coding:utf-8 -*-
import staticconf
'''
1.staticconf是一個庫剿另,用于從許多異構格式加載配置值并讀取這些值驰弄。
該過程分為兩個階段(配置加載和讀取配置值)。
'''
# 案例五鲫,給定兩個文件
# application.yaml
'''
pid : /var/run/app1.pid
storage_paths :
- / mnt / storage
- / mnt / nfs
min_date : 2014-12-12
groups :
users :
- userone
- usertwo
admins :
- admin
'''
# overrides.yaml
'''
max_files: 10
groups:
users:
- customuser
'''
# 加載配置
import staticconf
app_config = 'application.yaml'
app_custom = 'overrides.yaml'
staticconf.YamlConfiguration(app_config)
staticconf.YamlConfiguration(app_custom, optional=True) # 覆蓋app_config中的配置
# 讀取配置
import staticconf
pid = staticconf.read_string('pid')
storage_paths = staticconf.read_list_of_string('storage_paths')
users = staticconf.read_list_of_string('groups.users')
admins = staticconf.read_list_of_string('groups.admins')
min_date = staticconf.read_date('min_date')
print(pid)
print(storage_paths)
print(users)
print(admins)
print(min_date)
'''2.readers'''
# 例子 read an int
import staticconf
config = staticconf.NamespaceReaders('bling')
max_cycles = config.read_int('max_cycles')
ratio = config.read_float('ratio')
'''3.Schemas'''
from staticconf import schema
class SomethingUsefulSchema(schema.Schema):
namespace = 'useful_namespace'
config_path = 'useful'
max_value = schema.int(default=100)
ratio = schema.float()
msg = schema.any(config_key='msg_string', default="Welcome")
config = SomethingUsefulSchema()
print config.msg
'''4.getters'''
import staticconf
# Returns a ValueProxy which can be used just like an int
max_cycles = staticconf.get_int('max_cycles')
print "Half of max_cycles", max_cycles / 2
# 對象從命名空間使用NamespaceGetters對象
config = staticconf.NamespaceGetters('special')
ratio = config.get_float('ratio')
案例
8.* jinja2
安裝
pip install jinja2
案例
# -*- coding: utf-8 -*-
from jinja2 import Template
'''1.基本API用法'''
template = Template('hello {{ name }}')
print template.render(name='wangyifan')
# 使用包加載器來加載文檔的最簡單的方式如下:
from jinja2 import PackageLoader, Environment
env = Environment(loader=PackageLoader('python_project', 'templates')) # 創(chuàng)建一個包加載器對象
template = env.get_template('bast.html') # 獲取一個模板文件
template.render(name='daxin', age=18) # 渲染
'''2.jinja2基本語法 使用與Django DTL模板語法類似'''
# 1.控制結構 {% %}
# 2.變量取值 {{}}
# 3.注釋{# #}
{# 這是注釋 #}
{% for person in person_list %}
<p>name is {{ person.name }}</p>
{% endfor %}
'''3.繼承'''
{ % extend"base.html" %} # 繼承base.html文件
{ % blocktitle %} Dachenzi{ % endblock %} # 定制title部分的內容
{ % blockhead %}{{super()}} # 用于獲取原有的信息
< styletype = 'text/css' >.important{color: # FFFFFF }< / style >
{ % endblock %}
'''4.過濾器'''
# safe 渲染時值不轉義
# capitialize 把值的首字母轉換成大寫,其他子母轉換為小寫
# lower 把值轉換成小寫形式
# upper 把值轉換成大寫形式
# title 把值中每個單詞的首字母都轉換成大寫
# trim 把值的首尾空格去掉
# striptags 渲染之前把值中所有的HTML標簽都刪掉
# join 拼接多個值為字符串
# replace 替換字符串的值
# round 默認對數字進行四舍五入塑崖,也可以用參數進行控制
# int 把值轉換成整型
# 使用方式
# {{ 'abc' | upper }} >>> ABC
9.* blinker
Blinker為Python對象提供快速簡單的對象到對象和廣播信令规婆。
Blinker的核心很小但提供了強大的功能:
- 命名信號的全球注冊表
- 匿名信號
- 自定義名稱注冊表
- 永久或臨時連接的接收器
- 通過弱引用自動斷開接收器
- 發(fā)送任意數據有效載荷
- 從信號接收器收集返回值
- 線程安全
安裝
pip install blinker
案例
# -*-coding:utf-8 -*-
from blinker import signal
'''1.創(chuàng)建信號'''
# 信號通過signal()方法進行創(chuàng)建
sig = signal("sig")
sig is signal("sig")
# 每次調用signal('name')都會返回同一個信號對象蝉稳。因此這里signal()方法使用了單例模式耘戚。
'''2.訂閱信號'''
# 使用Signal.connect()方法注冊一個函數,每當觸發(fā)信號的時候饿这,就會調用該函數撞秋。
# 該函數以觸發(fā)信號的對象作為參數部服,這個函數其實就是信號訂閱者。
def subscriber(sender):
print('got a signal by %r' % sender)
ready = signal('ready')
print(ready.connect(subscriber))
'''3.觸發(fā)信號'''
# 使用Signal.send()方法通知信號訂閱者奉芦。
#下面定義類Processor剧蹂,在它的go()方法中觸發(fā)前面聲明的ready信號宠叼,send()方法以self為參數其爵,
# 也就是說Processor的實例是信號的發(fā)送者伸蚯。
class Processor:
def __init__(self,name):
self.name = name
def go(self):
ready = signal('ready')
ready.send(self)
print("Processing.")
complete = signal('complete')
complete.send(self)
def __str__(self):
return '<Processor %s>' % self.name
def __repr__(self):
return '<Processor %s>' % self.name
processor_a = Processor('a')
processor_a.go()
10.pytest
該pytest框架可以輕松編寫小型測試剂邮,然后進行擴展以支持應用程序和庫的復雜功能測試挥萌。
安裝
pip install -U pytest
pytest --version # 驗證安裝是否成功
案例
pytest_tools.py
這里我們定義了一個被測試函數func,該函數將傳遞進來的參數加1后返回狂芋。我們還定義了一個測試函數test_func用來對func進行測試憨栽。test_func中我們使用基本的斷言語句assert來對結果進行驗證徒像。
# -*- coding:utf-8 -*-
def func(x):
return x + 1
def test_answer():
assert func(3) == 5
在命令行執(zhí)行 pytest pytest_tools.py
執(zhí)行測試的時候锯蛀,我們只需要在測試文件test_sample所在的目錄下次慢,運行py.test即可。pytest會在當前的目錄下劈愚,尋找以test開頭的文件(即測試文件)闻妓,找到測試文件之后由缆,進入到測試文件中尋找test_開頭的測試函數并執(zhí)行。
通過上面的測試輸出是晨,我們可以看到該測試過程中舔箭,一個收集到了一個測試函數,測試結果是失敗的(標記為F)箫章,并且在FAILURES部分輸出了詳細的錯誤信息檬寂,幫助我們分析測試原因,我們可以看到"assert func(3) == 5"這條語句出錯了拿诸,錯誤的原因是func(3)=4塞茅,然后我們斷言func(3) 等于 5野瘦。