Python 入门
2024-03-14 10:43:35 1 举报
AI智能生成
登录查看完整内容
廖大佬的python 基础知识点梳理
作者其他创作
大纲/内容
os.getpid():返回当前进程ID
os.getppid():返回父进程ID
Linux 环境下
Process(target=函数名,args=参数)
join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步
对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了
Pool(子进程数) :创建子进程池,进程数默认为cpu核数
进程间通信
windows 和 Linux 环境下 可使用 multiprocessing 模块
多进程
操作系统能够进行运算调度的最小单位
threading.current_thread()函数,它永远返回当前线程的实例
threading.current_thread().name 获取当前线程名称,主线程默认是 MainThread,其他根据子线程参数传入确定
balance = 0lock = threading.Lock()def run_thread(n): for i in range(100000): # 先要获取锁: lock.acquire() try: # 放心地改吧: change_it(n) finally: # 改完了一定要释放锁: lock.release()
加锁
相关函数方法
参考文章
多线程
全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰
ThreadLocal
进程线程
s = r'ABC\\-001' # Python的字符串# 对应的正则表达式字符串不变:# 'ABC\\-001'
r前缀,就不用考虑转义的问题
Match 对象 分组
match()方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None
re.split() 切分字符串
非贪婪匹配(也就是尽可能少匹配)
默认贪婪匹配,即尽可能多的匹配字符
re.compile(r'正则表达式') 编译正则表达式,可重复使用
re 模块
正则表达式
>>> from datetime import datetime>>> now = datetime.now() # 获取当前datetime>>> print(now)2015-05-18 16:28:07.198690>>> print(type(now))<class 'datetime.datetime'>
获取当前日期和时间
获取指定日期和时间
1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp
整数位为秒
datetime 转换为 timestamp
>>> from datetime import datetime>>> t = 1429417200.0>>> print(datetime.fromtimestamp(t)) # 本地时间2015-04-19 12:20:00>>> print(datetime.utcfromtimestamp(t)) # UTC时间2015-04-19 04:20:00
timestamp转换为datetime
注意转换后的datetime是没有时区信息的
str转换为datetime
datetime加减,需引入 timedelta
本地时间转换为UTC时间
# 拿到UTC时间,并强制设置时区为UTC+0:00:>>> utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)>>> print(utc_dt)2015-05-18 09:05:12.377316+00:00# astimezone()将转换时区为北京时间:>>> bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))>>> print(bj_dt)2015-05-18 17:05:12.377316+08:00# astimezone()将转换时区为东京时间:>>> tokyo_dt = utc_dt.astimezone(timezone(timedelta(hours=9)))>>> print(tokyo_dt)2015-05-18 18:05:12.377316+09:00# astimezone()将bj_dt转换时区为东京时间:>>> tokyo_dt2 = bj_dt.astimezone(timezone(timedelta(hours=9)))>>> print(tokyo_dt2)2015-05-18 18:05:12.377316+09:00
先通过utcnow()拿到当前的UTC时间,时区转换的关键在于,拿到一个datetime时,要获知其正确的时区,然后强制设置时区,作为基准时间
时区转换
datetime模块
namedtuple 方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用
deque 是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
>>> from collections import defaultdict>>> dd = defaultdict(lambda: 'N/A')>>> dd['key1'] = 'abc'>>> dd['key1'] # key1存在'abc'>>> dd['key2'] # key2不存在,返回默认值'N/A'
注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入
defaultdict 给dict 设置默认值,避免抛出KeyError
OrderedDict的Key会按照插入的顺序排列,不是Key本身排序
OrderedDict 有序的dict
ChainMap 把一组dict串起来并组成一个逻辑上的dict
Counter 是一个简单的计数器
collections模块
$ ./backup.py -u root -p hello --database testdb backup.sqlparsed args:outfile = backup.sqlhost = localhostport = 3306user = rootpassword = hellodatabase = testdbgzcompress = False
parser.add_argument() 设定参数类型 默认值
parser.parse_args() 获取有效参数
argparse 库
>>> base64.b64encode(b'i\\xb7\\x1d\\xfb\\xef\\xff')b'abcd++//'>>> base64.urlsafe_b64encode(b'i\\xb7\\x1d\\xfb\\xef\\xff')b'abcd--__'>>> base64.urlsafe_b64decode('abcd--__')b'i\\xb7\\x1d\\xfb\\xef\\xff'
base64 模块
import hashlibmd5 = hashlib.md5()md5.update('how to use md5 in python hashlib?'.encode('utf-8'))print(md5.hexdigest())
hashlib.md5()
import hashlibsha1 = hashlib.sha1()sha1.update('how to use sha1 in '.encode('utf-8'))sha1.update('python hashlib?'.encode('utf-8'))print(sha1.hexdigest())
hashlib.sha1()
hashlib 模块
Hmac算法:Keyed-Hashing for Message Authentication。它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全
hmac 模块
>>> import itertools>>> natuals = itertools.count(1)>>> for n in natuals:... print(n)...123...
count()会创建一个无限的迭代器
>>> import itertools>>> cs = itertools.cycle('ABC') # 注意字符串也是序列的一种>>> for c in cs:... print(c)...'A''B''C''A''B''C'...
cycle()会把传入的一个序列无限重复下去
repeat()负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数:
chain()可以把一组迭代对象串联起来,形成一个更大的迭代器
groupby()把迭代器中相邻的重复元素挑出来放在一起
itertools 模块
任何对象,只要正确实现了上下文管理,就可以用于with语句
这个decorator接受一个generator,用yield语句把with ... as var把变量输出出去,然后,with语句就可以正常地工作了
with create_query('Bob') as q: q.query()
<h1>helloworld</h1>
@contextmanagerdef tag(name): print(\"<%s>\" % name) yield print(\"</%s>\" % name)with tag(\"h1\"): print(\"hello\") print(\"world\")
@contextmanager
from contextlib import closingfrom urllib.request import urlopenwith closing(urlopen('https://www.python.org')) as page: for line in page: print(line)
实际上是:@contextmanagerdef closing(thing): try: yield thing finally: thing.close()
closing()
contextlib 模块
模拟浏览器发送GET请求
Get 请求
模拟微博登录
Post 请求
urllib 模块
start_element事件,在读取<a href=\"/\">时;char_data事件,在读取python时;end_element事件,在读取</a>时
xml 模块
html 模块
常用内建模块
pip install pillow
Pillow 图像处理
pip install requests
requests 访问网络资源
pip install chardet
chardet 字符串编码
pip install psutil
psutil 获取系统信息
常用第三方模块
生成目录文件:bin include lib pyvenv.cfg
bin目录的内容,里面有python3、pip3等可执行文件,实际上是链接到Python系统目录的软链接
python3 -m venv <目录>就可以创建一个独立的Python运行环境
安装相关第三方模块会存放到lib目录下,不影响系统环境
继续进入bin目录,Linux/Mac用source activate,Windows用activate.bat激活该venv环境
退出当前的venv环境,使用deactivate命令
原理:把系统Python链接或复制一份到venv的环境,用命令source activate进入一个venv环境时,venv会修改相关环境变量,让命令python和pip均指向当前的venv环境
删除只需先确认该venv没有处于“激活”状态,然后直接把整个目录删掉就行
venv
入土
大小写敏感
tab缩进为4个空格
第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码
文件开头两行
规范
10000000000 == 10_000_000_000
多个0时允许数字中间 _ 分隔
没有大小限制
不可变变量
整数
0.000012 == 1.2e-5
1.23 乘 10 的 9次幂 == 1.23e9
科学计数法
也没有大小限制,但是超出一定范围就直接表示为inf(无限大)
float 浮点数
ord('A')
ord() 获取字符整数表示
chr(12323)
chr() 整数转换成对应字符
如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes
b'ABC'
'ABC'.encode('ascii')
b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'
'中文'.encode('utf-8')
中文无法编码为 ASCII
示例
encode() 表示字符串 str 编码为 字节 bytes
'ABC'
b'ABC'.decode('ascii')
中文
b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'.decode('utf-8')
errors='ignore' 忽略错误的字节
中
decode() 和 encode() 相反
3
len('ABC')
计算str 包含多少个字符
len(b'ABC')
5
len('中文'.encode('utf-8'))
计算 bytes 包含多少字节数
len()
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
占位符
'Age: 25. Gender: True'
'growth rate: 7 %'
用 %% 表示一个 %
'growth rate: %d %%' % 7
%
.1f指定了格式化参数(即保留1位小数)
format()
f-string
格式化方式
格式化
函数
str 字符串
True
False
bool布尔值
用 None 表示
None不能理解为0,因为0是有意义的,而None是一个特殊的空值
空值
跟普通变量没啥区别,约定使用大写表示
常量
超越索引范围返回 IndexError 错误
classmates[-2]
索引值带上 - 符号可倒序获取列表元素
classmates[1] = 'Sarah'
直接赋值某个索引上的值
一种有序集合
len() 获取list 元素个数
classmates.append('Adam')
append() 追加列表元素
insert() 指定位置插入元素
classmates.pop()
删除指定位置元素
classmates.pop(1)
my_string = \"hello\
将字符串转换为列表
将元组转换为列表
将集合转换为列表
将字典的键转换为列表
list()
list 列表
一种有序列表 和 list 非常相似,对应元素不可变
classmates = ()
初始化空tuple
初始化形式
tuple 元组
整数、字符串 可以
list 不可以
key必须是不可变对象
无序
key-value 形式存放元素,key 不存在直接报错
'Thomas' in d
通过 in 判断key 是否存在
d.get('Thomas')
不存在则返回默认值 -1
get() 方法,不存在返回 None
校验 key 是否存在
pop(key)
删除key
查找和插入的速度极快,不会随着key的增加而变慢
需要占用大量的内存,内存浪费多
同 list 列表区别
dict 字典
和dict类似,也是一组key的集合,但不存储value,没有重复的key
set(list) 初始化
add(key) 添加元素,可重复添加
remove(key) 删除元素
获取交集、并集
方法
set 集合
数据类型
and:逻辑与运算符,用于判断两个条件是否同时成立,只有当两个条件都为真时,整个表达式才为真
not:逻辑非运算符,用于对一个条件取反,如果条件为真,则返回假;如果条件为假,则返回真
in:成员运算符,用于检查某个值是否存在于序列(如列表、元组、字符串)中,如果存在则返回真,否则返回假
not in:成员运算符的否定形式,用于检查某个值是否不存在于序列中,如果不存在则返回真,否则返回假
is:身份运算符,用于比较两个对象的身份(即内存地址)是否相同,如果是同一个对象则返回真,否则返回假
运算符
def my_abs(x): if x >= 0: return x else: return -x
def 定义函数
>>> f = abs>>> f(-10)10
可修改系统函数,但一般不建议这样操作
函数名也是变量
返回值是一个tuple
返回多值
def add_end(L=[]): L.append('END') return L
错误示范
>>> add_end()['END']>>> add_end()['END']
def add_end(L=None): if L is None: L = [] L.append('END') return L
正确示范
定义默认参数要牢记一点:默认参数必须指向不变对象!
默认参数
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum
定义
在函数内部,参数numbers接收到的是一个tuple
外部参数已经是 list 或者 tuple
可变参数
传入 dict 字典类型变量
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
关键字参数
命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数
命名关键字参数
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
参数组合
参数
函数定义
def nop(): pass
空函数
RuntimeError: maximum recursion depth exceeded in comparison
由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。
特定递归形式可进行尾递归优化
递归函数
可以接收另一个函数作为参数
Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list
Iterator 和 Iterable 的区别可查看高级特性——迭代器
接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
map()
reduce()
返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回lis
埃氏筛选法获取质数
过滤序列
filter()
接收一个key函数来实现自定义的排序
反向排序,传入第三个参数 reverse=True
sorted()
高阶函数
def lazy_sum(*args): def sum(): ax = 0 for n in args: ax = ax + n return ax return sum
函数中返回函数,即闭包函数
每次调用都会返回一个新的函数,即使传入相同的参数
>>> f1()9>>> f2()9>>> f3()9
原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9
可再创建一个函数,用该函数的参数绑定当前循环变量当前的值
返回函数不要引用任何循环变量,或者后续会发生变化的变量
def inc(): x = 0 def fn(): nonlocal x x = x + 1 return x return fnf = inc()print(f()) # 1print(f()) # 2
使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。
返回函数
lambda 创建,格式:lambda 参数(多个逗号隔开): 表达式
只能有一个表达式,不用写return,返回值就是该表达式的结果
匿名函数
@logdef now(): print('2015-3-25')
无参数
@log('execute')def now(): print('2015-3-25')
使用 functools.wraps 方法获取 func 真正方法名
有参数
@语法 把相关函数设置到对应需装饰的函数定义处
装饰器
把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单
偏函数
生成从 2 到 5(但不包括 6)的整数序列
这将生成从 0 到 4(但不包括 5)的整数序列。
for i in range(5): print(i)
函数用于创建一个整数序列,通常用于循环中指定范围
range()
打开二进制文件,使用 rb 模式打开
编码不规范会发生 UniocodeDecodeError,可传入 errors='ignore' 忽略报错
读取非UTF-8 编码的文本文件,需传入 encoding 参数
传入标识符 w 或 wb 可写文本文件或二进制文件
'r':只读模式,文件必须存在,如果文件不存在会引发异常
'rb':以二进制格式打开一个文件,只读。文件必须存在,如果文件不存在会引发异常
只读模式
'w':只写模式,打开一个文件只用于写入。如果文件存在则将其覆盖,如果文件不存在则创建新文件
'wb':以二进制格式打开一个文件,只用于写入。如果文件存在则将其覆盖,如果文件不存在则创建新文件
'w+':读写模式,打开一个文件用于读写。如果文件存在则将其覆盖,如果文件不存在则创建新文件
'wb+':以二进制格式打开一个文件,用于读写。如果文件存在则将其覆盖,如果文件不存在则创建新文件
只写模式
'a':追加模式,打开一个文件用于写入。如果文件存在,文件指针将会放在文件的结尾。如果文件不存在则创建新文件
'ab':以二进制格式打开一个文件,用于追加。如果文件存在,文件指针将会放在文件的结尾。如果文件不存在则创建新文件
'a+':读写模式,打开一个文件用于读写。如果文件存在,文件指针将会放在文件的结尾。如果文件不存在则创建新文件
'ab+':以二进制格式打开一个文件,用于追加和读取。如果文件存在,文件指针将会放在文件的结尾。如果文件不存在则创建新文件
追加模式
模式
open() 打开文件,不存在则抛出 IOError 错误,存在则返回文件描述符对象 file-like Object
>>> from io import StringIO>>> f = StringIO()>>> f.write('world!')6>>> print(f.getvalue())world!
>>> from io import StringIO>>> f = StringIO('Hello!\Hi!\Goodbye!')>>> while True:... s = f.readline()... if s == '':... break... print(s.strip())...Hello!Hi!Goodbye!
StirngIO() ,读写字符串
>>> from io import BytesIO>>> f = BytesIO()>>> f.write('中文'.encode('utf-8'))6>>> print(f.getvalue())b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'
>>> from io import BytesIO>>> f = BytesIO(b'\\xe4\\xb8\\xad\\xe6\\x96\\x87')>>> f.read()b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'
BytesIO() ,读写bytes
f.read() 一次性读取文件全部内容,可传入 size ,反复调用 read(size) 避免一次性读取大文件
f.readline() 每次读取一行内容
f.readlines() 一次读取所有内容并按行返回list
不必调用f.close()方法
使用 with 语句保险
操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。
f.write() 写入文件
因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的
两种关闭方法,避免异常时无法关闭文件描述符
f.close() 文件使用完毕后必须关闭
offset:偏移量,表示从某个位置开始移动的字节数。
0:表示从文件开头开始计算偏移量(默认值)
1:表示从当前位置开始计算偏移量
2:表示从文件末尾开始计算偏移量
whence:可选参数,表示参照位置,可以取三个值
f.seek() 移动文件指针
IO 函数
操作文件和目录
对象序列化
对象序列化写入文件
读取文件序列化内容
pickle.dumps() 序列化
只支持python语法读取
pickle模块
dict
{}
list
[]
str
\"string\"
int或float
1234.56
True/False
true/false
None
null
即以上python类型为可序列化对象
json 类型 对应 python 类型
json.dumps 支持写入 file-like Object
default 参数支持传入将class转化为dict 的方法
序列化为 json
json 反序列化
class 对象处理
序列化为 json
>>> json_str = '{\"age\
反序列化为python对象
json 操作
json 模块
序列化
其他函数
score = 'B'if score == 'A': print('score is A.')elif score == 'B': print('score is B.')elif score == 'C': print('score is C.')else: print('invalid score.')
条件判断
age = 15match age: case x if x < 10: print(f'< 10 years old: {x}') case 10: print('10 years old.') case 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18: print('11~18 years old.') case 19: print('19 years old.') case _: print('not sure.')
匹配多值、一定范围、单个值
匹配列表
模式匹配
sum = 0for x in range(101): sum = sum + xprint(sum)
for 循环
n = 1while n <= 100: if n > 10: # 当n = 11时,条件满足,执行break语句 break # break语句会结束当前循环 print(n) n = n + 1print('END')
n = 0while n < 10: n = n + 1 if n % 2 == 0: # 如果n是偶数,执行continue语句 continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行 print(n)
while 循环
循环
流程控制
前10个数,每两个取一个:
list 有序集合切片
tuple 元组切片
>>> 'ABCDEFG'[:3]'ABC'>>> 'ABCDEFG'[::2]'ACEG'
字符串 切片
切片
判断是否可迭代
>>> for ch in 'ABC':... print(ch)...ABC
str 迭代
使用 for 循环迭代
使用索引迭代
使用 enumerate() 迭代
使用 while 循环迭代
list 迭代
dict 迭代
迭代
for 循环加上 if 判断
使用两层循环,可以生成全排列
使用两个甚至多个变量
所有字符串变为小写
if ... else
列表生成式
>>> g = (x * x for x in range(10))>>> for n in g:... print(n)... 0149162536496481
列表生成式初始化一个生成器,使用()接收
使用 yield 关键字
请务必注意:调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。
用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中
生成器
直接作用于for 循环的对象统称为可迭代对象:Iterable
isinstance()判断一个对象是否是Iterable对象
Iterable 可迭代对象
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
通过iter() 函数转换
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的
Iterator 迭代器
迭代器
高级特性
如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类
class Student(object): pass
class Animal(object): def run(self): print('Animal is running...')class Dog(Animal): passclass Cat(Animal): pass
Class Child(Father):
在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类
检查变量是否某个类
多重继承:MixIn
继承
子类覆盖父类相同方法名
多态
Class 首字母大写类名(object):
与实例绑定的函数
self就指向创建的实例本身
两个下划线开头 __,只用内部可以访问
和特殊变量区分开,__name__、__score__,特殊变量是可以公开访问的
私有变量
class Student(object): name = 'Student'
直接在class中定义属性
类属性
实例绑定属性的方法是通过实例变量,或者通过self变量
和类属性的区别
实例属性
属性
>>> s = Student()>>> s.name = 'Michael' # 动态给实例绑定一个属性>>> print(s.name)Michael
对其他实例不起作用
实例方法
所有实例均可调用
类方法
仅对当且类起作用的限制外部绑定实例属性字段
使用__slots__
外部绑定
>>> s = Student()>>> s.score = 60 # OK,实际转化为s.set_score(60)>>> s.score # OK,实际转化为s.get_score()60>>> s.score = 9999Traceback (most recent call last): ...ValueError: score must between 0 ~ 100!
通过属性形式调用方法
首先转换为方法调用,在执行return self.birth时,又视为访问self的属性,于是又转换为方法调用,造成无限递归,最终导致栈溢出报错RecursionError
class Student(object): # 方法名称和实例变量均为birth: @property def birth(self): return self.birth
属性的方法名不要和实例变量重名
@property 装饰器
构造器方法,当一个实例被创建时调用,用于初始化对象。
class Example: def __str__(self): return \"Example object\"
定义对象的“非正式”或可打印的字符串表示,通过print()函数或str()调用。
__str__(self)
定义对象的“正式”字符串表示,用于调试和其他开发者需要精确了解对象的情况。如果没有提供__str__,则会使用__repr__作为替代。
__repr__(self)
class Example: def __del__(self): print(\"Example object is being deleted\")
析构器方法,当对象被销毁(回收)之前调用。
__del__(self)
允许类的一个实例像函数那样被调用
获取序列的元素,如 obj[key]
设置序列的元素,如 obj[key] = value。
class Example: def __len__(self): return 10obj = Example()print(len(obj))
返回容器的大小。
__len__(self)
使对象成为迭代器。
__iter__(self) 和 __next__(self)
魔术方法
类定义
实例变量 = 类名()
实例(Instance)初始化
>>> type(123)==type(456)True>>> type(123)==intTrue>>> type('abc')==type('123')True
函数类型:types.FunctionType
方法类型:types.BuildtinFunctionType
匿名函数:types.LambdaType
>>> import types>>> def fn():... pass...>>> type(fn)==types.FunctionTypeTrue>>> type(abs)==types.BuiltinFunctionTypeTrue>>> type(lambda x: x)==types.LambdaTypeTrue>>> type((x for x in range(10)))==types.GeneratorTypeTrue
types 模块常量
判断两个变量类型是否相同
class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
参数说明
ORM 编写会用到,目前只需了解即可
另外一种动态创建类的方法:元类 metaclass
动态创建类
type() 函数
一个对象是否是该类型本身,或者位于该类型的父继承链上
isinstance() 函数
获得一个对象的所有属性和方法
dir() 函数
getattr()
setattr()
hasattr()
获取对象信息
属性、方法操作
类
文件www.py的模块名就是mycompany.web.www
mycompany ├─ web │ ├─ __init__.py │ ├─ utils.py │ └─ www.py ├─ __init__.py ├─ abc.py └─ utils.py
通过包(Package)按目录组织模块,包目录下必须存在__init__.py 文件
不能和Python自带的模块名称冲突
检查是否存在,可在python交互环境执行 import 模块 ,成功即存在
模块管理
第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;
第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;
第6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;
#!/usr/bin/env python3# -*- coding: utf-8 -*-' a test module '__author__ = 'Michael Liao'
代码规范
_xxx 或者 __xxx 变量不应该被直接使用
外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public
非公开(private)变量
作用域
初始化
pypi 官网
[global]index-url = https://pypi.tuna.tsinghua.edu.cn/simple
pip.ini 或者 pip.conf 文件 新增国内清华大学PyPI 镜像
设置PyPI 镜像
pip install XXXX
一个基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库
Anaconda会把系统Path中的python指向自己自带的Python,并且,Anaconda安装的第三方模块会安装在Anaconda自己的路径下,不影响系统已安装的Python目录
Anaconda
常用工具
安装第三方模块
默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中
>>> import sys>>> sys.path.append('/Users/michael/my_py_scripts')
修改sys.path
PYTHONPATH该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。
设置环境变量
增加要搜素的目录
不建议使用 from module_name import * 导入所有,会导致命名冲突
从一个模块中导入一个或多个特定的函数、类或变量,而不是导入模块中的所有内容
import xxx模块
模块引入
安装使用
模块
try ... except ... except ... else... finally ...
try ... except ... finally ...
无论是否异常都会执行finally,可以不设置 finally
所有错误类型都继承自 BaseException
异常捕获
从上往下调用
调用栈
filename:指定日志输出的文件名,如果设置了这个参数,日志信息将会被写入到指定的文件中 否则日志消息会被发送到标准输出(console)
level:指定日志记录的级别阈值,只有大于等于该级别的日志消息才会被记录下来
日志记录的时间,格式由datefmt参数指定
%(asctime)s
日志级别(如DEBUG、INFO、WARNING、ERROR、CRITICAL)
%(levelname)s
日志消息内容
%(message)s
format:指定日志输出的格式,可以自定义输出的格式
'%Y-%m-%d %H:%M:%S'
datefmt:指定日期和时间的格式
filemode:指定日志文件的打开模式,默认为 'a'(追加模式)
stream:指定日志输出流,如果设置了 stream 参数,则日志信息将会被发送到指定的流对象,而不是文件
logging.basicConfig()只能在程序的启动时被调用一次,后续对它的调用将不会有任何效果,除非在此之前调用了logging.shutdown()
logging.basicConfig() 参数
logging 模块
记录错误
# err_raise.pyclass FooError(ValueError): passdef foo(s): n = int(s) if n==0: raise FooError('invalid value: %s' % s) return 10 / nfoo('0')
try: 10 / 0except ZeroDivisionError: raise ValueError('input error!')
raise语句如果不带参数,就会把当前错误原样抛出。此外,在except中raise一个Error,还可以把一种类型的错误转化成另一种类型
raise 抛出错误实例
抛出错误
错误处理
assert语句本身就会抛出AssertionError
启动Python解释器时可以用-O参数来关闭assert
assert 断言
logging 日志记录
p 变量名,可查看变量
n,单步执行代码
q,结束调试
单步调试过于麻烦
-m pdb 启动,例如 python -m pdb err.py
# err.pyimport pdbs = '0'n = int(s)pdb.set_trace() # 运行到这里会自动暂停print(10 / n)
设置断点,,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行
pdb.set_trace()
pdb 调试器
调试
测试类需继承 unittest.TestCase
以 test 开头的方法才是测试方法
类以及方法定义
with self.assertRaises(KeyError): value = d['empty']
期待抛出指定类型的Error
assertTrue(x):断言 x 为 True
assertFalse(x):断言 x 为 False
def test_attrerror(self): d = Dict() with self.assertRaises(AttributeError): value = d.empty
要确保在 with 块内执行的代码确实会引发指定的异常,否则测试将失败
if __name__ == '__main__': unittest.main()
新增以下代码后直接运行 python mydict_test.py
python -m unittest mydict_test
命令行通过参数-m unittest直接运行单元测试
运行
单元测试
文档测试
错误、调试和测试
入门
Python
0 条评论
回复 删除
下一页