import pickle
import json
# 序列化,把变量从内存中变成可存储或传输的过程
d = dict(name='Tom', age=20, score=99)
# 把任意对象序列化为十六进制的bytes
print(pickle.dumps(d))
# 返回一个标准的json字符串
print("从json串中读取到:", json.dumps(d))
# 直接把对象序列化后写入文件
with open('dump.txt', 'wb') as f:
pickle.dump(d, f)
# 从dump.txt文件中读取一个对象
with open('dump.txt', 'rb') as f:
d = pickle.load(f)
print("从文件中读取到:", d)
输出:
b’\x80\x04\x95$\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x03Tom\x94\x8c\x03age\x94K\x14\x8c\x05score\x94Kcu.’
从json串中读取到: {“name”: “Tom”, “age”: 20, “score”: 99}
从文件中读取到: {‘name’: ‘Tom’, ‘age’: 20, ‘score’: 99}
from enum import Enum, unique
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
# @unique装饰器保证没有重复值,从Enum派生出自定义类
@unique
class Weekday(Enum):
Sun = 0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
one_day = Weekday.Mon
print(one_day)
print(Weekday.Tue.value)
for name, member in Weekday.__members__.items():
print(name, '=>', member)
输出:
Jan => Month.Jan , 1
Feb => Month.Feb , 2
Mar => Month.Mar , 3
Apr => Month.Apr , 4
May => Month.May , 5
Jun => Month.Jun , 6
Jul => Month.Jul , 7
Aug => Month.Aug , 8
Sep => Month.Sep , 9
Oct => Month.Oct , 10
Nov => Month.Nov , 11
Dec => Month.Dec , 12
Weekday.Mon
2
Sun => Weekday.Sun
Mon => Weekday.Mon
Tue => Weekday.Tue
Wed => Weekday.Wed
Thu => Weekday.Thu
Fri => Weekday.Fri
Sat => Weekday.Sat
class Student(object):
# python内置的@property装饰器就是负责把一个方法变成属性调用的
@property
def score(self):
return self._score
# 把一个setter方法变为属性赋值
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer')
if value < 0 or value > 100:
raise ValueError('score must be 0~100')
self._score = value
s = Student()
s.score = 60
print(s.score)
输出:
60
# 可变参数求和
def calc_sum(*args):
ax = 0
for n in args:
ax += n
return ax
calc_sum(1, 2, 3, 4)
# 不返回求和结果,返回求和的函数
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax += n
return ax
return sum
# 闭包,返回函数内部引用了局部变量args,获得的函数没有立即执行
def count():
fs = []
for i in range(2, 5):
def f():
return i * i
fs.append(f)
return fs
# 一个函数可以返回一个计算结果,也可以返回一个函数,该函数并未执行,返回函数中不要引用任何可能会变化的变量
f1, f2, f3 = count()
print(f1(), ' ', f2(), ' ', f3())
输出:
16 16 16
# python内置了字典dict,其他语言中也称为map,具有极快的查找速度
d = {'Michael': 95, 'Tom': 99, 'Jack':88}
print(d['Michael'])
d['Lucy'] = 89
# 避免键不存在的错误,通过in判断键是否存在
print('Thomas' in d)
# 如果键不存在返回None或者指定默认值
print(d.get('Thomas'))
print(d.get('Thomas', -1))
# 使用pop删除键,同时删除对应的值
d.pop('Lucy')
print(d)
输出:
95
False
None
-1
{‘Michael’: 95, ‘Tom’: 99, ‘Jack’: 88}
# set是一组不可重复键的集合
s = set([1, 2, 3, 5, 3])
print(s)
s.add(4)
s.remove(4)
输出:
{1, 2, 3, 5}
def fact(n):
if n == 1:
return 1
else:
return fact(n-1) * n
print(fact(10))
输出:
3628800
# 获取对象信息
import types
# 使用type方法判断基本类型,如果一个变量指向函数或类也可以使用
print(type(123))
print(type('str'))
print(type(None))
print(type(abs))
print(type(123) == type(456))
print(type(123) == int)
print(type('abc') == str)
print(type('abc') == type(123))
# 判断一个对象是否是函数可以使用types模块中定义的变量
def fn():
pass
print(type(fn) == types.FunctionType)
print(type(abs) == types.BuiltinFunctionType)
print(type((x for x in range(10))) == types.GeneratorType)
# 使用isinstance判断class类型,dir函数获得对象的所有属性和方法
print(dir('ABC'))
print('ABC'.__len__())
# 自定义的类,如果也想使用len(myObj),需要写一个__len__()方法
class MyDog(object):
def __len__(self):
return 100
dog = MyDog()
print(len(dog))
# 类的属性和方法
class MyObject(object):
def __init__(self):
self.x = 9
def power(self):
return self.x * self.x
obj = MyObject()
print(hasattr(obj, 'x'), obj.x)
setattr(obj, 'y', 19)
print(hasattr(obj, 'y'), getattr(obj, 'y'))
输出:
True
True
True
False
True
True
True
[‘add’, ‘class’, ‘contains’, ‘delattr’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘getnewargs’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘mod’, ‘mul’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘rmod’, ‘rmul’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘capitalize’, ‘casefold’, ‘center’, ‘count’, ‘encode’, ‘endswith’, ‘expandtabs’, ‘find’, ‘format’, ‘format_map’, ‘index’, ‘isalnum’, ‘isalpha’, ‘isascii’, ‘isdecimal’, ‘isdigit’, ‘isidentifier’, ‘islower’, ‘isnumeric’, ‘isprintable’, ‘isspace’, ‘istitle’, ‘isupper’, ‘join’, ‘ljust’, ‘lower’, ‘lstrip’, ‘maketrans’, ‘partition’, ‘removeprefix’, ‘removesuffix’, ‘replace’, ‘rfind’, ‘rindex’, ‘rjust’, ‘rpartition’, ‘rsplit’, ‘rstrip’, ‘split’, ‘splitlines’, ‘startswith’, ‘strip’, ‘swapcase’, ‘title’, ‘translate’, ‘upper’, ‘zfill’]
3
100
True 9
True 19
import os
print(os.name) # 获取操作系统类型
#print(os.environ) # 获取环境变量
#print(os.environ.get('PATH', 'default')) # 获取环境变量值
print(os.path.abspath('.')) # 查看当前目录的绝对路径
# 在某个目录下创建或删除目录
#os.path.join('c:\\PythonDemo', '111') # 合成路径可以正确处理不同操作系统的路径分隔符
os.mkdir('c:\\PythonDemo\\222')
os.rmdir('c:\\PythonDemo\\222')
#os.rename('test.txt', 'test.py') # 重命名文件
#os.remove('test.py') # 删除文件
print([x for x in os.listdir('.') if os.path.isdir(x)]) # 列出当前目录下所有目录
# 列出所有的.py文件
print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1] == '.py'])
# 用print()再括号中加上字符串,可以在屏幕上输出制定的文字
print('Hello World!!!')
# print()函数可以接受多个字符串,用逗号隔开,一次打印每个字符串,遇到逗号会输出一个空格
print('Tom,', 'Jack,', 'Lucy')
# print()可以打印整数或计算结果
print('100+200=', 100+200)
# input()可以让用户输入字符串并放入到一个变量中
name = input()
print(name)
输出:
Hello World!!!
Tom, Jack, Lucy
100+200= 300
李四
# 写文件
f = open('C:\\PythonDemo\\test.txt', 'w')
f.write('Hello World!!!')
f.close()
# 读文件,读二进制文件使用rb
f = open('C:\\PythonDemo\\test.txt', 'r')
f.read()
f.close()
# 自动释放资源
with open('C:\\PythonDemo\\test.txt', 'r') as f:
print(f.read())
for line in f.readlines():
print(line.strip())
# python除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数
# x是一个位置参数,必须传入并且仅有一个参数
def power(x):
return x * x
print(power(50))
# 参数n默认值为2
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print(power(5, 2))
# 可变参数把多个参数作为一个列表或者元组传过来
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc([1, 2, 3, 4, 5]))
# 关键字允许传入0个或一个含参数名的参数,这些关键字参数在函数内部自动组装成一个dict
# 可变参数允许传入0个或者任意个参数,可变参数在函数调用时自动组装成一个tuple
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Michael', 50)
person('Bob', 33, city='南京')
# 命名关键字参数用特殊的分隔符星号后面的变量
def person(name, age, *, city, job):
print(name, age, city, job)
# 参数组合:必选参数、默认参数、可变参数/命名关键字参数和关键字参数的顺序
person('Tom', 33, city='南京', job='工程师')
输出:
2500
25
55
name: Michael age: 50 other: {}
name: Bob age: 33 other: {‘city’: ‘南京’}
Tom 33 南京 工程师
# 切片就是选区一个列表或元组的部分元素
L = ['Tom', 'Jackson', 'Thomas', 'Jack', 'Lucy']
print([L[0], L[1], L[2]]) # 获取前三个元素
# 取前N个元素
res = []
n = 4
for i in range(n):
res.append(L[i])
print(res)
print(L[0:3]) # 使用切片操作,包括0不包括3
print(L[:3]) # 第一个索引是0
print(L[-1]) # 支持倒序切片
print(L[-2:])
# 创建一个0-99的数列,获取前10个和后10个数
L = list(range(99))
print(L[:10])
print(L[-10:])
print(L[10:20]) # 获取前11-20个数
print(L[:10:2]) # 前10个每两个出一个数
print(L[::5]) # 每5个取一个数
#print(L[:]) # 复制一个列表
# tuple也是一种list,tuple不可变,也可以使用切片,结果还是tuple
print((0, 1, 2, 3, 4, 5)[:3])
print('ABCDEFG'[:3]) # 字符串也可以看成一种list
print('ABCDEFG'[::2])
输出:
[‘Tom’, ‘Jackson’, ‘Thomas’]
[‘Tom’, ‘Jackson’, ‘Thomas’, ‘Jack’]
[‘Tom’, ‘Jackson’, ‘Thomas’]
[‘Tom’, ‘Jackson’, ‘Thomas’]
Lucy
[‘Jack’, ‘Lucy’]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[89, 90, 91, 92, 93, 94, 95, 96, 97, 98]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[0, 2, 4, 6, 8]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
(0, 1, 2)
ABC
ACEG
# 很多时候数据读写不一定是文件,也可以在内存中读写
# StringIO在内存中读写字符串
from io import StringIO, BytesIO
f = StringIO()
f.write('hello')
f.write(' ')
print(f.getvalue()) # 获得写入后的字符串
f = StringIO('Hello!!\nHi!\nGoodbye!')
while True:
s = f.readline()
if s == '':
break
print(s.strip())
# 操作二进制数据
f = BytesIO()
# 写入的是经过utf-8编码的bytes
f.write('中文'.encode('utf-8'))
print(f.getvalue())
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
s = f.read()
print(s.decode('utf-8'))
import json
jsonString = '{"arrayOfNums":[{"number":0},{"number":2}],' \
'"arrayOfFruits":[{"fruit":"apple"},{"fruit":"banana"},{"fruit":"pear"}]}'
jsonObj = json.loads(jsonString)
print(jsonObj.get('arrayOfNums'))
print(jsonObj.get('arrayOfNums')[0].get('number'))
输出:
[{‘number’: 0}, {‘number’: 2}]
0
import functools
print(int('12345'))
print(int('12346', base=8))
def int2(x, base=2):
return int(x, base)
# 把一个函数某些参数固定住,返回一个新的函数
int2 = functools.partial(int, base=2)
print(int2('10000'))
输出:
12345
5350
16
# 交互命令行通过help(abs)查看abs函数的帮助信息
# 调用函数时,如果传入参数数量不对或参数类型不对,抛出TypeError错误
# 1、python内置很多可以直接调用的函数,可以参考官网
# 2、数据类型转换函数,比如int()可以把其他类型数据转换为整数
print(int('123'))
print(float('12.32'))
print(str(1.22))
print(int(12.32))
print(str(100))
print(bool(1))
print(bool(''))
输出:
123
12.32
1.22
12
100
True
False
def log(func): #装饰器在运行期间动态增加功能
def wrapper(*args, **kw):
print('call %s()'%func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2022-08-31')
f = now
print(f())
print(now.__name__)
输出:
call now()
2022-08-31
None
wrapper
# 传入函数时,不需要显式地定义函数,直接传入匿名函数更加方便
L = list(map(lambda x: x*x, range(1, 10)))
# 匿名函数只能有一个表达式,不用写return,返回值就是该表达式结果
print(L)
# 匿名函数也是一个函数对象
f = lambda x: x*x
print(f(5))
输出:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
25
# 如果给定一个list或者tuple,可以通过for循环来便利这个list或者tuple,这种遍历叫做迭代
# Python使用for ... in 来完成的,for可以用在list或者tuple上,也可以作用在其他可迭代对象上
from typing import Iterable
d = {'a':1, 'b':2, 'c':3}
# 迭代key
for key in d:
print(key)
# 迭代value
for val in d.values():
print(val)
# 同时迭代key和value
for k, v in d.items():
print(k, v)
# 判断对象是否是可迭代对象
print(isinstance('abc', Iterable))
print(isinstance([1, 2, 3], Iterable))
print(isinstance(123, Iterable))
# 采用内置的enumerate函数把list变为索引元素对
for i, val in enumerate(['A', 'B', 'C']):
print((i, val))
# 遍历元组
for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
names = ['Andy', 'Tom', 'Jerry', 'Lucy']
for name in names:
print(name)
print(list(range(5)))
import math
def my_abs(x):
if x >= 0:
return x
else:
return -x
# 空函数
def nop():
pass
# 返回多个值
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
x, y = move(100, 100, 60, math.pi/6)
print(x, y)
# 如果列表元素可以按照某种算法推算出来,可以在循环的过程中不断推算出后续元素,就不必创建完整的list,从而节省大量的空间
# 创建一个列表L和生成器G,通过next()方法获取下一个值
L = [x * x for x in range(10)]
G = (x * x for x in range(10))
print(L)
print(G)
for n in G:
print(n)
# 斐波那契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a+b
n += 1
return 'done'
print(fib(10))
# ThreadLocal变量是全局变量,但每个线程只能读写自己线程的独立副本,互不干扰
# ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,Http请求,用户身份信息等
import threading
class Student(object):
def __init__(self, name):
self.name = name
# 创建全局ThreadLocal对象
local_school = threading.local()
def process_student():
std = local_school.student
print('Hello, %s (in %s)'%(std, threading.current_thread().name))
def process_thread(name):
local_school.student = name
process_student()
t1 = threading.Thread(target=process_thread, args=('Tom',), name='Thread-1')
t2 = threading.Thread(target=process_thread, args=('Jerry',), name='Thread-2')
t1.start()
t2.start()
t1.join()
t2.join()
age = 6
if age >= 10:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
classmates = ['Andy', 'Bob', 'Clark']
print(len(classmates))
print(classmates[0], classmates[-1])
classmates.append('David')
classmates.insert(1, 'Eric')
print(classmates)
classmates.pop(1)
classmates[1] = 'Jack'
print(classmates)
# tuple一旦初始化就不能修改
classmates = ('Andy', 'Bob', 'Clark')
print(classmates)
# 只有一个元素的元组定义时必须添加一个逗号来消除歧义
t = (1,)
print(t)
# python字符串都是以unicode编码的
print('包含中文的字符串')
print(ord('A')) # 获取字符的整数表示
print(chr(65), chr(25991)) # 把编码转换成对应的字符
# python字符串类型是str,在内存中以unicode表示,一个字符对应若干个字节。
# 如果在网络上传输,或者保存到磁盘上,需要把str转变为以字节为单位的bytes。
print(b'ABC', 'ABC'.encode('ascii'), '中文'.encode('utf-8'), b'ABC'.decode('ascii'),
b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'), len('ABC'), len('中文'))
# 格式化%s字符串替换,%d整数替换,%f浮点数占位符,%x十六进制整数
print('Hello, %s'%'world')
# 格式化整数和浮点数还可以指定补零和小数的位数
print('%2d-%02d'%(3, 1))
print('%.2f'%3.1415926)
import os
# 列表推导式是python内置的用来创建列表的生成式
print(list(range(1, 11)))
M = [x * x for x in range(1, 11)]
print(M)
# 选出偶数平方
print([x * x for x in range(1, 11) if x % 2 == 0])
# 使用两层循环生成全排列
print([m + n for m in 'ABC' for n in 'XYZ'])
# 列出当前目录下所有文件和文件名
# print([d for d in os.listdir('.')])
# for循环使用多个变量
d = {'x': 'A', 'y': 'B', 'z': 'C'}
for k, v in d.items():
print((k, v))
print([k + '=' + v for k, v in d.items()])
# 将一个列表中所有字符串小写
L = ['Hello', 'World', 'IBM', 'Apple']
print([s.lower() for s in L])
print(isinstance('Abc', str))
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[4, 16, 36, 64, 100]
[‘AX’, ‘AY’, ‘AZ’, ‘BX’, ‘BY’, ‘BZ’, ‘CX’, ‘CY’, ‘CZ’]
(‘x’, ‘A’)
(‘y’, ‘B’)
(‘z’, ‘C’)
[‘x=A’, ‘y=B’, ‘z=C’]
[‘hello’, ‘world’, ‘ibm’, ‘apple’]
True
from multiprocessing import Process
import os
def run_proc(name):
print('Run child process %s (%s)...'%(name, os.getpid()))
if __name__ == '__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
import subprocess
# subprocess模块可以方便启动一个子进程
print('$ nslookup www.python.org')
r = subprocess.call(['nslookup', 'www.python.org'])
print('Exit code:', r)
p = subprocess.Popen(['nslookup'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = p.communicate(b'set q=mx\npython.org\nexit\n')
#print(output.decode('utf-8'))
print('Exit code:', p.returncode)
# 如果需要启动大量的子进程,可以使用进程池的方式批量创建子进程
# from multiprocessing import Pool
# import os, time
# def long_time_task(name):
# print('Run task %s (%s)...'%(name, os.getpid()))
# start = time.time()
# time.sleep(3)
# end = time.time()
# print('Task %s runs %0.2f seconds.'%(name, (end - start)))
# if __name__ == '__main__':
# print('Parent process %s.'%os.getpid())
# p = Pool(4)
# for i in range(5):
# p.apply_async(long_time_task, args=(i,))
# print('Waiting for all subprocess done...')
# p.close()
# p.join()
# print('All subprocesses done.')
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name:%s)'%self.name
def __getattr__(self, item):
if item == 'score':
return 99
def __call__(self): # 可以直接调用实例
print('My name is %s.'%self.name)
__repr__ = __str__
print(Student('Bob'))
s = Student('Tom')
print(s())
callable(max)
from functools import reduce
def add(x, y, f):
return f(x) + f(y)
print(add(-5, 6, abs))
def f(x):
return x * x
r = map(f, range(1, 10))
print(list(r))
def add(x, y):
return x + y
print(reduce(add, [x for x in range(1, 10) if x % 2 == 1]))
def is_odd(n):
return n % 2 == 1
print(list(filter(is_odd, [1, 2, 3, 4, 6, 9, 15])))
print(sorted([36, 5, -12, 9])) # 从小到大排序
print(sorted([36, 5, -12, 9], key=abs))
print(sorted(['tom', 'zoo', 'Credit'], key=str.lower, reverse=True))
输出:
11
[1, 4, 9, 16, 25, 36, 49, 64, 81]
25
[1, 3, 9, 15]
[-12, 5, 9, 36]
[5, 9, -12, 36]
[‘zoo’, ‘tom’, ‘Credit’]