1 逻辑运算 and,or, not
(1)在没有()的情况下not 优先级高于 and,and优先级高于or,即优先级关系为( )>not>and>or,同一优
先级从左往右计算。
(2)计算下面例题的运算结果
1 3>4 or 4<3 and 1==1 #False 2 1 < 2 and 3 < 4 or 1>2 #True 3 2 > 1 and 3 < 4 or 4 > 5 and 2 < 1# True 4 1 > 2 and 3 < 4 or 4 > 5 and 2 > 1 or 9 < 8 #False 5 1 > 1 and 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6 #False 6 not 2 > 1 and 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6 #False
总结: x or y , x为真,值就是x,x为假,值是y;x and y, x为真,值是y,x为假,值是x。
or找真,and找假
2 python基础数据类型
(1)str
~~切片语法:str[start:end:step] start: 起始位置,end: 结束位置,step:步长
~~切片规则:顾头不顾尾
~~str 字符串操作:
1 ret6 = s13.find("tory") # 查找'tory'的位置, 如果没有返回-1 2 print(ret6)
3 ret8 = s13.index("sylar") # 求索引位置. 注意. 如果找不到索引. 程序会报错
# 条件判断 s14 = "123.16" s15 = "abc" s16 = "_abc!@" # 是否由字母和数字组成 print(s14.isalnum()) print(s15.isalnum()) print(s16.isalnum()) # 是否由字母组成 print(s14.isalpha()) print(s15.isalpha()) print(s16.isalpha()) # 是否由数字组成, 不包括小数点 print(s14.isdigit()) print(s14.isdecimal()) print(s14.isnumeric()) # 这个比较牛B. 中文都识别. print(s15.isdigit()) print(s16.isdigit())
(2)列表 list
# 迭代添加 lst = ["王志文", "张一山", "苦海无涯"] lst.extend(["麻花藤", "麻花不疼"]) print(lst) #['王志文', '张一山', '苦海无涯', '麻花藤', '麻花不疼']
# 切片修改
lst[1:4:3] = ["麻花藤", "哇靠"] # 切片修改也OK. 如果步长不是1, 要注意. 元素的个数 print(lst)
#排序 lst = [1, 11, 22, 2] lst.sort() # 排序. 默认升序 print(lst) lst.sort(reverse=True) # 降序 print(lst) #反转 lst = ["太白", "太黑", "五色", "银王", "日天", "太白"] print(lst) lst.reverse() print(lst) l = len(lst) # 列表的长度 print(l)
注意,嵌套的多层列表采用降维操作.一层一层的看就好.
循环删除列表中的元素问题:
由于删除元素会导致元素的索引改变, 所以容易出现问题. 尽量不要再循环中直接去删
除元素. 可以把要删除的元素添加到另⼀个集合中然后再批量删除.
dict中的fromkey(),可以帮我们通过list来创建⼀一个dict
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"]) print(dic) 结果: {'jay': ['周杰伦', '麻花藤'], 'JJ': ['周杰伦', '麻花藤']}
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"]) print(dic) dic.get("jay").append("胡⼤大") print(dic) 结果: {'jay': ['周杰伦', '麻花藤', '胡⼤大'], 'JJ': ['周杰伦', '麻花藤', '胡⼤大']} # 代码中只是更改了jay那个列表. 但是由于jay和JJ用的是同一个列表. 所#以. 前面那个改了. 后面那个也会跟着改
(3)元组 tuple
元组: 俗称不可变的列表.又被成为只读列表, 元组也是python的基本数据类型之一, 用小括号括起来, 里面可以放任何数据类型
的数据, 查询可以. 循环也可以. 切片也可以. 但就是不能改.关于不可变, 注意: 这里元组的不可变的意思是子元素不可变. 而子元素
内部的子元素是可以变, 这取决于子元素是否是可变对象
tu = (1, "哈哈", [], "呵呵") # tu[2] = ["fdsaf"] # 这么改不行 tu[2].append("麻花藤") # 可以改了. 没报错 tu[2].append("王剑林") print(tu)
注意,元组中如果只有一个元素. 一定要添加一个逗号, 否则就不是元组.
(4)字典 dict
字典中的key必须是可哈希的不可变的数据,dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. 而hash表不是连续的. 所以不能进行切片工作.
它只能通过key来获取dict中的数据,
#字典的修改 dic = {"id": 123, "name": 'sylar', "age": 18} dic1 = {"id": 456, "name": "麻花藤", "ok": "wtf"} dic.update(dic1) # 把dic1中的内容更新到dic中. 如果key重名. 则修改替换. 如果不存在key, 则新增. print(dic) print(dic1
#利用items()解构 print(dic.items()) # dict_items([('id', 123), ('name', 'sylar'), ('age', 18), ('ok', '科比')]) 这个东西也是list. 只不过list中装的是tuple for key, value in dic.items(): # ?? 这个是解构 print(key, value) # 解构 a, b = 1, 2 print(a, b)
嵌套的字典也采用降维操作.
3 小数据池
小数据池(常量池): 把我们使用过的值存储在小数据池中.供其他的变量使用.
小数据池给数字和字符串使用, 其他数据类型不存在.
对于数字: -5~256是会被加到⼩小数据池中的. 每次使⽤用都是同⼀一个对象.
对于字符串串:
1. 如果是纯文字信息和下划线. 那么这个对象会被添加到小数据池
2. 如果是带有特殊字符的. 那么不会被添加到小数据池. 每次都是新的
3. 如果是单⼀一字母*n的情况. 'a'*20, 在20个单位内是可以的. 超过20个单位就不会添加
到小数据池中
注意(一般情况下): 在py文件中. 如果你只是单纯的定义⼀个字符串串. 那么一般情况下都是会
被添加到小数据池中的. 我们可以这样认为: 在使用字符串的时候, python会帮我们把字符串进行缓存
, 在下次使⽤的时候直接指向这个字符串即可. 可以节省很多内存.
4 深浅拷贝
浅拷贝. 只会拷贝第一层. 第二层的内容不会拷贝. 所以被称为浅拷贝
深度拷贝. 把元素内部的元素完全进行拷贝复制. 不会产生一个改变另一个跟着改变的问题.
5 文件操作
seek(n) 光标移动到n位置, 注意, 移动的单位是byte. 所以如果是UTF-8的中⽂文部分要
是3的倍数.通常我们使⽤用seek都是移动到开头或者结尾.
移动到开头: seek(0)
移动到结尾: seek(0,2) seek的第二个参数表示的是从哪个位置进行偏移, 默认是0, 表
示开头, 1表示当前位置, 2表示结尾
truncate() 截断文件
#truncate() 截断⽂文件 f = open("⼩小娃娃", mode="w", encoding="utf-8") f.write("哈哈") # 写⼊入两个字符 f.seek(3) # 光标移动到3, 也就是两个字中间 f.truncate() # 删掉光标后⾯面的所有内容 f.close() f = open("⼩小娃娃", mode="r+", encoding="utf-8") content = f.read(3) # 读取12个字符 f.seek(4) print(f.tell()) f.truncate() # 后⾯面的所有内容全部都删掉 # print(content) f.flush() f.close()
深坑请注意: 在r+模式下. 如果读取了内容. 不论读取内容多少. 光标显示的是多少. 再写入
或者操作文件的时候都是在结尾进行的操作.
所以如果想做截断操作. 记住了. 要先挪动光标. 挪动到你想要截断的位置. 然后再进行截断
关于truncate(n), 如果给出了了n. 则从开头进行截断, 如果不给n, 则从当前位置截断. 后面的内
容将会被删除
6 函数
1.函数: 对代码块和功能的封装和定义
2.返回值:
如果return什什么都不写 或者 ⼲干脆不写return .那么返回的就是None
如果return后⾯面写了了⼀一个值. 则调⽤用者可以接收⼀一个结果
如果return后⾯面写了了多个结果, 则调⽤用者可以接收⼀一个tuple, 调⽤用者可以直接解构成
多个变量量
3.函数的参数:
(1) 形参
写在函数声明的位置的变量量叫形参. 形式上的⼀一个完整. 表⽰示这个函数需要xxx
(2)实参
在函数调⽤用的时候给函数传递的值. 叫实参, 实际执⾏行行的时候给函数传递的信息. 表⽰示给函数xxx
4.参数的分类
1 位置参数
2 关键字参数
3.混合参数(位置参数必须在关键字参数前面)
5,动态传参
形参的位置顺序:
位置参数 > *args > 默认值参数 > **kwargs
6.命名空间
加载顺序: 内置命名空间>全局命名空间>局部命名空间(函数被执行的时候)
取值顺序:局部命名空间>全局命名空间>内置命名空间
7. 关键字global和nonlocal
global表示. 不再使用局部作用域中的内容了.而改用全局作用域中的变量
nonlocal 表示在局部作用域中, 调用父级命名空间中的变量(非全局变量).
8.
函数名.__name__可以查看函数的名字
函数名.__doc__ 可以查看函数的⽂文档注释
7 装饰器
1.闭包
闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包.
我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是
闭包. 返回None就不是闭包.
闭包的作用就是让一个变量能够常驻内存. 供后面的程序使用.
2.饰器的完整模型代码
开闭性原则
装饰器的作用: 在不改变原有代码的基础上给⼀个函数增加功能
def wrapper(func): def inner(*args, **kwargs): '''在执行目标函数之前要执行的内容''' ret = func(*args, **kwargs) '''在执行目标函数之后要执行的内容''' return ret return inner # @wrapper 相当于 target_func = wrapper(target_func) 语法糖 @wrappe def target_func(): print("我是目标函数") # 调⽤目标函数 target_func()
3.*args和**kwargs什什么时候打散, 什什么时候聚合
1. 接收参数的时候是聚合, 参数声明
2. 传递参数的时候是打散, 给函数传递实参
4 带参装饰器模型
from functools import wraps def wrapper_out(flag): def wrapper(fn): @wraps(fn) def inner(*args, **kwargs): if flag == True: # 查的严啊. 先问问吧 print("问问⾦金金⽼老老板啊, ⾏行行情怎么样.") ret = fn(*args, **kwargs) print("⺾艹, ⾦金金⽼老老板骗我") return ret else: # 查的不不严. 你慌什什么 ret = fn(*args, **kwargs) return ret return inner return wrapper
@wrapper_out(False) # 传递True和False来控制装饰器器内部的运⾏行行效果
def yue():
print("约⼀一次⼜又不不会死")
5. 多个装饰器装饰同⼀个函数
def wrapper1(fn): def inner(*args, **kwargs): print("111") ret = fn(*args, **kwargs) print("222") return ret return inner def wrapper2(fn): def inner(*args, **kwargs): print("333") ret = fn(*args, **kwargs) print("444") return ret return inner @wrapper2 @wrapper1 def eat(): print("我想吃⽔水果") eat()
结果: 333 111 我想吃⽔水果 222 444