- 1.入门
- 2.基本语法
- 循环 items
- Strategy: Iterate over a copy
- Strategy: Create a new collection
- 遍历
- enumerate 传入可迭代数据, 返回序列和值组成的元组
- break、continue 与其他语言相同
- 3.基本数据类型
- 4.练习
- 初始化当前目录对象
- 绝对路径
- 列出目录中的文件和目录
- 拼接路径,可以直接使用 / ,在Windows上会转成 \
- 也可以使用 joinpath
- 文件全名
- 后缀名
- 不包含后缀的文件名
- 分离各目录
- 是否存在
- pathlib中提供了直接替换文件名,后缀名的方法
- with_name,with_stem,with_suffix
- 打开文件
- 复制文件
- 将文件 src 拷贝到文件或目录 dst
- 如果是目录则用当前的文件名
- 删除目录
- 5.项目
1.入门
1.1 官方文档,特性和应用场景有哪些
官方文档
Python是一门简单易学, 功能强大的编程语言。
它开源, 免费, 可用于C或者C++的扩展, 或者封装
特性: 语法优雅, 动态类型, 解释运行, 部分面向对象
场景: 编写脚本, 快速构建几乎所有的小型应用,比如桌面程序, 手机程序, 任何服务器, 游戏等等
所谓部分面向对象, 就是有类, 也有内置函数, 有的类型有构造方法, 有的用函数 比如Java是严格面向对象, 所有类型都有方法 Golang 更面向组合, 更多使用函数和接口, 少量使用结构体
1.2 安装与运行
安装
官网下载安装, 完成后在中断输入 pythonx.x
运行
x.x 对应版本号, 比如
python3.9
, 然后打印 hello worldPython 3.8.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print('hello world')
hello world
直接运行py文件, 如下 test.py, 在终端中输入
pythonx.x test.py
if __name__ == '__main__':
print('hello world')
1.3 镜像(选答)
安装依赖时的镜像
pip install {redis} -i https://pypi.douban.com/simple
1.4 编辑器(选答)
Python可以使用 ipython, jupyter, VSCode, Pycharm 等
推荐学习时使用 ipython, 写项目用 Pycharm, 两者都有提示
前者是增强交互型shell, 后者是IDE1.5 包管理工具
# 安装依赖库
pip install requests
# 指定版本
pip install requests==2.6.0
# 升级到最新版本
pip install --upgrade requests
# 卸载
pip uninstall requests
# 显示库的信息
pip show requests
# 显示安装的包
pip list
# 生成一个类似的已安装包列表
pip freeze > requirements.txt
# 从文件中安装依赖
pip install -r requirements.txt
2.基本语法
2.1 判断
# if, Python里没有switch
>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
2.2 循环
```python
循环 items
Strategy: Iterate over a copy
for user, status in users.copy().items(): if status == ‘inactive’:
del users[user]
Strategy: Create a new collection
active_users = {} for user, status in users.items(): if status == ‘active’: active_users[user] = status
遍历
enumerate 传入可迭代数据, 返回序列和值组成的元组
In [1]: squal = [1, 2, 4, 9, 16] In [2]: for i, v in enumerate(squal): …: print(f’index={i}, value={v}’) …: index=0, value=1 index=1, value=2 index=2, value=4 index=3, value=9 index=4, value=16
break、continue 与其他语言相同
<a name="LbQY0"></a>
### 2.3 函数
```python
# pass, 占位语句, Python特有
def aaa():
pass # 什么也不做
# 函数
# 使用 def 关键字, 可接收单个参数, 列表和 键值对
def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
for kw in keywords:
print(kw, ":", keywords[kw])
# 调用
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
# 输出
'''
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch
'''
2.4 错误与异常
# 捕获异常
while True:
try:
x = int(input("Please enter a number: "))
except ValueError:
print("Oops! That was no valid number. Try again...")
# 可以省略异常名,以用作通配符。但应谨慎使用,这种方式很容易掩盖真正的编程错误!
except:
print('some error happens!')
# 使用 else 子句比向 try 子句添加额外的代码要好,可以避免意外捕获非 try ... except 语句保护的代码触发的异常。
else:
print(f'you input {x}')
# 在实际应用程序中,finally 子句对于释放外部资源(例如文件或者网络连接)非常有用,无论是否成功使用资源。
finally:
print("executing finally clause")
# 抛出异常
raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: HiThere
2.5 面向对象
# 类的定义
# 括号中是继承的父类
class Dog(FatherClass):
kind = 'canine' # class variable shared by all instances
def __init__(self, name):# 构造函数
self.name = name # instance variable unique to each instance
self.tricks = [] # creates a new empty list for each dog
# 方法, 都要加 self 关键字
def add_trick(self, trick):
self.tricks.append(trick)
实例变量与类变量
一般来说,实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法
正确的类设计应该使用实例变量, 不使用类变量
私有变量
那种仅限从一个对象内部访问的“私有”实例变量在 Python 中并不存在
但是,大多数 Python 代码都遵循这样一个约定:带有一个下划线的名称 (例如 _spam) 应该被当作是 API 的非公有部分 (无论它是函数、方法或是数据成员)。 这应当被视为一个实现细节,可能不经通知即加以改变
3.基本数据类型
3.1 数字
# this is the first comment
spam = 1 # and this is the second comment
# ... and now a third!
text = "# This is not a comment because it's inside quotes."
# 加减乘除,取余,取整
>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # division always returns a floating point number
1.6
>>> 17 / 3 # classic division returns a float
5.666666666666667
>>> 17 // 3 # floor division discards the fractional part
5
>>> 17 % 3 # the % operator returns the remainder of the division
2
# 取小数点后两位
>>> round(123.345, 2)
123.34
# 整数与小数转换
In [1]: int(123.4)
Out[1]: 123
In [2]: float(123)
Out[2]: 123.0
# 指数
>>> 5 ** 2 # 5 squared
25
>>> 2 ** 7 # 2 to the power of 7
128
# 十进制转其他进制
# 注意结果都是字符串
In [24]: deci = 100
# 二进制
In [26]: bin(deci)
Out[26]: '0b1100100'
# 十六进制
In [25]: hex(deci)
Out[25]: '0x64'
# 八进制
In [27]: oct(deci)
Out[27]: '0o144'
# 其他进制转十进制
# 结果是数字
# 二进制
In [28]: int('0b1000', 2)
Out[28]: 8
# 八进制
In [29]: int('0o1000', 8)
Out[29]: 512
# 十六进制
In [31]: int('0x20', 16)
Out[31]: 32
3.2 字符
# 单引号和双引号都可以
In [4]: print('hello lisay')
hello lisay
# 单引号中的双引号可以直接显示,不用转义
# 同理反过来也一样
In [6]: print('"hi", I said')
"hi", I said
# 转义字符
In [7]: print('hi \n i said')
hi
i said
# 显示原始字符, 加个 r
In [8]: print(r'hi \n i said')
hi \n i said
# 多行输出, 用三个单引号或者双引号, 并且加上 \
# 反斜杠表示不包含本行的换行符
In [9]: print("""\
...: Usage: thingy [OPTIONS]
...: -h Display this usage message
...: -H hostname Hostname to connect to
...: """)
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
# 字符拼接
# 可以使用 + 号
In [13]: print('py' + 'thon')
python
# 也可以用join
In [61]: 'python'.join(['a', 'b'])
Out[61]: 'apythonb'
# 格式化输出
In [15]: print("{} can be {}".format("strings", "interpolated"))
strings can be interpolated
# 指定字段
In [16]: print("{name} can be {action}".format(name="strings", action="interpolated"))
strings can be interpolated
# 3.6 新增, 在字符串前加 f
In [62]: f'I love {word}'
Out[62]: 'I love python'
# Python中的字符串可以被索引, 当做只读列表操作
# 赋值和数组越界都会报错
In [18]: word = 'python'
# 截取下标为1的字符
In [19]: print(word[1])
y
# 负数表示从最后开始,-1表示最后一个
In [20]: print(word[-1])
n
# 左包含右不包含
In [21]: print(word[1:4])
yth
# 省略左边表示从0开始
# 省略右边表示到最后结束
In [22]: print(word[:4])
pyth
# 长度, 这个特殊一点
In [32]: len(word)
Out[32]: 6
# 遍历, 也可以像列表那样
In [54]: for i in word:
...: print(i)
...:
p
y
t
h
o
n
# 其他都有其方法,可以查看文档
# 正则表达式
import re
# 将正则表达式编译成 Pattern 对象
pa = re.compile(r'\d{1,2,3}')
# match 方法返回一个对象, 只找第一个匹配的
In [51]: g = pa.match('12321')
In [53]: g.group()
Out[53]: '12'
# findall 返回一个列表, 所有匹配的结果
In [50]: pa.findall('12321')
Out[50]: ['12', '32']
3.3 列表
# 定义
>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
# 查找
#根据索引找值
>>> squares[0] # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:] # slicing returns a new list
[9, 16, 25]
# 根据值找索引
In [103]: squares.index(9)
Out[103]: 1
# 新增
# 单个元素
In [65]: squares.append([36, 49])
In [66]: squares
Out[66]: [1, 4, 9, 16, 25, [36, 49]]
# 任意位置, (index, value)
In [113]: stack.insert(0, 6)
# + 号拼接
>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# extend 拼接
In [70]: squares.extend([36, 49])
In [71]: squares
Out[71]: [1, 4, 9, 16, 25, 36, 49]
# 修改
# 单个元素
In [73]: squares[0] = 0
In [74]: squares
Out[74]: [0, 4, 9, 16, 25, 36, 49]
# 批量修改
In [75]: squares[:2] = [1, 2]
In [76]: squares
Out[76]: [1, 2, 9, 16, 25, 36, 49]
# 删除
# 根据索引删除
In [68]: squares.pop(-1)
Out[68]: 25
# 使用 del 内置函数删除
In [104]: del(squares[0])
# 根据值删除
In [81]: squares.remove(1)
# 批量删除
In [107]: del(squares[0:2])
# 全部删除
In [96]: squares.clear()
In [96]: del squares[:]
# 甚至可以删除变量
del squares
# 长度
In [83]: len(squares)
Out[83]: 4
# 倒序遍历
# 注意 range 函数也是左包含右不包含
In [99]: for i in range(len(stack)-1, -1, -1):
...: print(stack[i])
...:
5
4
3
3.4 字典(键值对)
# 定义
>>> tel = {'jack': 4098, 'sape': 4139}
# 新增
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
# 查询
>>> tel['jack']
4098
# 删除
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
# 获取键的列表
>>> list(tel)
['jack', 'guido', 'irv']
# 遍历
In [121]: for i in tel:
...: print(f'key={i}, value={tel[i]}')
# 同时遍历键和值
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k,v in knights.items():
... print(k,"=",v)
...
gallahad = the pure
robin = the brave
# 将键排序
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
3.5 集合
可以使用大括号 或者 set() 函数创建set集合,创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典
>>> student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
>>> print(student) # 重复的元素被自动去掉
{'Jim', 'Jack', 'Mary', 'Tom', 'Rose'}
>>> 'Rose' in student # membership testing(成员测试)
True
>>> # set可以进行集合运算
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a
{'a', 'b', 'c', 'd', 'r'}
>>> a - b # a和b的差集
{'b', 'd', 'r'}
>>> a | b # a和b的并集
{'l', 'm', 'a', 'b', 'c', 'd', 'z', 'r'}
>>> a & b # a和b的交集
{'a', 'c'}
>>> a ^ b # a和b中不同时存在的元素
{'l', 'm', 'b', 'd', 'z', 'r'}
3.6 栈和队列
# 栈的实现
# 可以通过列表实现
In [84]: stack = [3, 4, 5]
# 入栈
In [85]: stack.append(6)
In [86]: stack
Out[86]: [3, 4, 5, 6]
# 出栈
In [87]: stack.pop()
Out[87]: 6
In [88]: stack
Out[88]: [3, 4, 5]
# 队列的实现
# 也可以通过列表实现, 但是将第一个元素弹出,速度上比较慢
# 推荐使用 collections.deque
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
3.7 元组
元组是不可变序列, 不能增, 删, 改, 只能遍历
定义, 遍历, 合并, 与列表的相互转换
# 定义
>>> t = 12345, 54321, 'hello!'
# 查询
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
# 遍历
In [135]: for i in t:
...: print(i)
...:
12345
54321
hello!
# 合并
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
tup3 = tup1 + tup2
print (tup3)
# 元组 -> 列表
In [138]: list(t)
Out[138]: [12345, 54321, 'hello!']
# 列表 -> 元组
In [137]: squal = [1, 1]
In [137]: tuple(squal)
Out[137]: (1, 1)
基本数据类型的相互转换都是通过其构造函数
4.练习
4.1 时间
使用 datetime 模块, 用于处理日期和时间
包括 time, date, datetime, timedelta(时间间隔) 等等
更多用法参考文档
from datetime import datetime
# 当前时间对象
now = datetime.now()
# 当前时间戳, 单位: 秒
int(now.timestamp())
1631193729
# 格式化输出, 年-月-日 时:分:秒
now.strftime('%Y-%m-%d %H:%M:%S')
'2021-09-09 21:22:09'
# 格式化时间转时间戳
ftime = datetime.strptime('2021-09-09 21:22:09', '%Y-%m-%d %H:%M:%S')
int(ftime.timestamp())
1631193729
# 时间戳转格式化时间
timestemp = datetime.fromtimestamp(1631193729)
timestemp.strftime('%Y-%m-%d %H:%M:%S')
'2021-09-09 21:22:09'
4.2 文件与目录
4.2.1 文件
# 有两种方式: 内置open 和 os.open
# 后者是适用于底层的 I/O。常规用途请使用内置函数 open
# 全部读
file = open("a.txt","r")
file.read('')
file.close()
# 不用close
with open("a.txt", "r") as f:
print(f.read())
# 按行读
for line in open("chapter_4_with.txt", 'r'):
print(line)
# 按行读并获取行号
for line_num, content in enumerate(open(file_path)):
print 'line numbers=%s,content=%s' % (line_num, content)
# 创建文件并写入
with open("a.txt", "w") as f:
f.write('abc')
# 追加写入
with open("a.txt", "a") as f:
f.write('abc')
# 删除文件
import os
os.remove('a.txt')
# 修改文件名
os.rename('a.txt', 'b.txt')
# 文件大小,单位:字节
fsize = os.stat('b.txt')
fsize.st_size
# 替换文件中的字符
# 如果直接写,会覆盖原有内容
# 如果先调用read,再写入,则变为追加,所以要seek(0)
#
with open('a.txt', 'r+') as f:
content = f.read()
c = content.replace('hello', 'bbbb')
print(c)
f.seek(0)
f.write(c)
文件模式:
分两类:文件类型(t、b)与操作类型(r、w、a、x,+)
字符 | 意义 |
---|---|
‘r’ | 读取(默认) |
‘w’ | 写入,并先清空文件 |
‘x’ | 排它性创建,如果文件已存在则失败 |
‘a’ | 写入,如果文件存在则在末尾追加 |
‘b’ | 二进制模式 |
‘t’ | 文本模式(默认) |
‘+’ | 打开用于更新(读取与写入) |
- 模式 ‘w+’ 与 ‘w+b’ 将打开文件并清空内容。
- 模式 ‘r+’ 与 ‘r+b’ 将打开文件并不清空内容, 即覆盖写入。
4.2.2 目录
推荐使用 pathlib 模块— 面向对象的的文件系统路径,原来的os.path
虽然可以用,不过略显麻烦。
推荐使用 shutil 模块,提供了一系列对文件和文件集合的高阶操作。特别是提供了一些支持文件拷贝和删除的函数。 ```python In [1]: from pathlib import Path初始化当前目录对象
In [2]: p = Path(‘.’)绝对路径
In [3]: p.absolute() Out[3]: PosixPath(‘/Users/renyangwei/Documents/PythonProject/examples’)列出目录中的文件和目录
In [4]: for i in p.iterdir(): …: print(i) …: turtle_example.py .DS_Store file_ext_example.py b.txt拼接路径,可以直接使用 / ,在Windows上会转成 \
In [7]: ftxt = p / ‘b.txt’ In [9]: ftxt.absolute() Out[9]: PosixPath(‘/Users/renyangwei/Documents/PythonProject/examples/b.txt’)也可以使用 joinpath
In [14]: ftxt.joinpath(‘abc’) Out[14]: PosixPath(‘b.txt/abc’)
文件全名
In [8]: ftxt.name Out[8]: ‘b.txt’
后缀名
In [10]: ftxt.suffix Out[10]: ‘.txt’
不包含后缀的文件名
In [12]: ftxt.stem Out[12]: ‘b’
分离各目录
p = PurePath(‘/usr/bin/python3’) p.parts (‘/‘, ‘usr’, ‘bin’, ‘python3’)
p = PureWindowsPath(‘c:/Program Files/PSF’) p.parts (‘c:\‘, ‘Program Files’, ‘PSF’)
是否存在
In [13]: ftxt.exists() Out[13]: True
pathlib中提供了直接替换文件名,后缀名的方法
with_name,with_stem,with_suffix
p = PureWindowsPath(‘c:/Downloads/pathlib.tar.gz’) p.with_name(‘setup.py’) PureWindowsPath(‘c:/Downloads/setup.py’)
打开文件
In [15]: with ftxt.open() as f: …: f.read()
复制文件
In [30]: import shutil
将文件 src 拷贝到文件或目录 dst
如果是目录则用当前的文件名
In [31]: shutil.copy2(‘b.txt’, ‘c.txt’) Out[31]: ‘c.txt’
删除目录
shutil.rmtree(‘mdir’)
<a name="Sndth"></a>
### 4.3 加密
Python 中使用 [hashlib](https://docs.python.org/zh-cn/3/library/hashlib.html) 模块,支持多种加密
> 输入字符串对象是不被支持的,因为哈希基于字节而非字符
```python
import hashlib
# MD5
In [19]: m = hashlib.md5(b'12345')
In [20]: m.hexdigest()
Out[20]: '827ccb0eea8a706c4c34a16891f84e7b'
# sha1
In [21]: m = hashlib.sha1()
# 重复调用相当于单次调用并传入所有参数的拼接结果: m.update(a); m.update(b) 等价于 m.update(a+b)
In [22]: m.update(b'12345')
In [23]: m.hexdigest()
Out[23]: '8cb2237d0679ca88db6464eac60da96345513964'
4.4 异步
使用 asyncio 模块,其实就是Python中的协程。
asyncio 是用来编写 并发 代码的库,使用 async/await 语法。
asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。
示例
>>> import asyncio
# 定义异步函数,使用 async 关键字
>>> async def main():
... print('hello')
... await asyncio.sleep(1)
... print('world')
# 调用异步函数
>>> asyncio.run(main())
hello
world
并发运行
import asyncio
async def factorial(name, number):
f = 1
for i in range(2, number + 1):
print(f"Task {name}: Compute factorial({number}), currently i={i}...")
await asyncio.sleep(1)
f *= i
print(f"Task {name}: factorial({number}) = {f}")
return f
async def main():
# Schedule three calls *concurrently*:
L = await asyncio.gather(
factorial("A", 2),
factorial("B", 3),
factorial("C", 4),
)
print(L)
asyncio.run(main())
# Expected output:
#
# Task A: Compute factorial(2), currently i=2...
# Task B: Compute factorial(3), currently i=2...
# Task C: Compute factorial(4), currently i=2...
# Task A: factorial(2) = 2
# Task B: Compute factorial(3), currently i=3...
# Task C: Compute factorial(4), currently i=3...
# Task B: factorial(3) = 6
# Task C: Compute factorial(4), currently i=4...
# Task C: factorial(4) = 24
# [2, 6, 24]
4.5 命令行
推荐使用 click 模块,一眼就能看懂,非常方便
安装
pip install click
官网示例
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo(f"Hello {name}!")
if __name__ == '__main__':
hello()
运行
$ python hello.py --count=3
Your name: John
Hello John!
Hello John!
Hello John!
$ python hello.py --help
Usage: hello.py [OPTIONS]
Simple program that greets NAME for a total of COUNT times.
Options:
--count INTEGER Number of greetings.
--name TEXT The person to greet.
--help Show this message and exit.
4.6 测试
推荐使用 unittest 模块
import unittest
# 继承unittest.TestCase
class TestStringMethods(unittest.TestCase):
# 以 test_ 名称开头的方法
def test_upper(self):
# 断言
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
# 运行单元测试
unittest.main()
4.7 图片
操作图片推荐使用 pillow 库
# pip3 install Pillow
from PIL import Image
from PIL import ImageFilter
from PIL import ImageDraw
from PIL import ImageFont
img = Image.open("meinv.jpg")
def convert():
"""照片去色"""
img01 = img.convert("L")
img01.save("img01.jpg")
def filter():
"""模糊"""
img02 = img.filter(ImageFilter.GaussianBlur(radius=10))
img02.save("img02.jpg")
def rotate():
"""旋转"""
img03 = img.rotate(90)
img03.save("img03.jpg")
def transpose():
"""翻转"""
img04 = img.transpose(Image.FLIP_LEFT_RIGHT)
img04.save("img04.jpg")
def thumbnail():
"""缩略图"""
size = (100, 100)
img05 = img.copy()
img05.thumbnail(size)
img05.save("img05.jpg")
def addText():
img06 = img.copy()
draw = ImageDraw.Draw(img06)
font = ImageFont.truetype(r"~/Library/Fonts/Arimo for Powerline.ttf", size=30)
color = "rgb(255,0,0)"
draw.text((50, 50), "hello", fill=color, font=font)
img06.save("img06.jpg")
if __name__ == '__main__':
# convert()
# filter()
# rotate()
# transpose()
# thumbnail()
addText()
4.8 数据处理
import json
# 对象 -> Json字符
class Student(object):
def __init__(self, name, age, score,reward):
self.name = name
self.age = age
self.score = score
self.reward = reward
s = Student('Bob', 20, 88,["三好学生","优秀团干","最佳辩手"])
print(json.dumps(obj=s.__dict__,ensure_ascii=False))
# Json字符串 -> 对象
class Student(object):
def __init__(self, name, age, score,reward):
self.name = name
self.age = age
self.score = score
self.reward = reward
def dict2student(d):
return Student(d['name'], d['age'], d['score'],d['reward'])
json_str = '{"name": "Bob", "age": 20, "score": 88, "reward": ["三好学生", "优秀团干", "最佳辩手"]}'
student = json.loads(json_str,object_hook=dict2student)
print(type(student))
print(student.name)
xml
推荐使用 xml.etree.ElementTree 模块
示例数据
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
代码
import xml.etree.ElementTree as ET
# 解析文件,如果是字符串使用 fromstring 方法
tree = ET.parse('country_data.xml')
# 根元素
root = tree.getroot()
# 标签
root.tag
# 属性
root.attrib
# 遍历一级节点
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
# 遍历所有子树
>>> for neighbor in root.iter('neighbor'):
... print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
# 仅查找当前元素的直接子元素
>>> for country in root.findall('country'):
... rank = country.find('rank').text
# get 访问属性的值
... name = country.get('name')
... print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68
# 增删改
# 使用 Element.text 修改文本字
# 使用 Element.set() 方法添加和修改属性
# 使用 Element.append() 添加新的子元素
# 使用 Element.remove() 删除元素
# 解析带有命名空间的 XML
# 手动为 find() 或 findall() 的 xpath 中的每个标记或属性添加 URI
root = fromstring(xml_text)
for actor in root.findall('{http://people.example.com}actor'):
name = actor.find('{http://people.example.com}name')
print(name.text)
for char in actor.findall('{http://characters.example.com}character'):
print(' |-->', char.text)
4.9 执行系统命令
import os
def excute(cmd):
cmd += " 2>&1"
f = os.popen(cmd,"r")
s = f.read()
ret = f.close()
print("ret=", ret)
if ret != None:
print("err=",s)
else:
print("execute sucess!")
5.项目
本人一般就用来写脚本,爬虫、服务端、游戏、Excel、邮件等等以后等有需要或者学到了再补充。